VK said:
In Usenet, that line belongs on the top of all the quotations, in order to
make it easy to quote that later. You have been told before numerous times.
Now you are definitely kidding.
No, he is not.
{"key1":"value1"}
structure is a valid JSON object data but it is not JavaScript syntax
compatible for the above spelled reasons and leads to "invalid label"
syntax error.
Only if used in a context where `{'...`}' are parsed as delimiters of a
/Block/ statement and consequently `"key": "value"' as a
/LabelledStatement/, e.g.:
/Program/
→ /SourceElements/
→ /SourceElement/
→ /Statement/
→ /Block/
→ { /StatementList/ }
→ { /Statement/ }
→ { /LabelledStatement/ }
→ { /Identifier/ : /Statement/ }
[ES3F, 12.1]
Richard explained that to you in greater detail; but obviously, and
unsurprisingly, you have not been paying attention.
By creating the assignment context like
var obj = {"key1":"value1"}
we are masking this potential error
No, in that context it is parsed, as Richard already explained to you, as a
perfectly valid /AssignmentExpression/:
/Statement/
→ /VariableStatement/
→ var /VariableDeclarationList/ ;
→ var /VariableDeclaration/ ;
→ var /Identifier/ /Initialiser/ ;
→ var /Identifier/ = /AssignmentExpression/ ;
→ ...
→ var /Identifier/ = /ObjectLiteral/ ;
[ES3F, 11.3.1]
and successfully instantiating obj over assignment.
Whatever that is supposed to mean.
If - as many others - we are using JavaScript allowed
shortcut without quotes around the key name then we also masking this
ticking bomb:
{"key1":"value1"}
You don't know what you are talking about.
And
var obj = eval( '{key1:"value1"}' );
window.alert(typeof obj); // string
?
Since the string value of eval() is (to be) parsed as a /Program/, what
looks like an /ObjectLiteral/ at first is in fact parsed as a /Block/
statement:
/Program/
→ /SourceElements/
→ /SourceElement/
→ /Statement/
→ /Block/
→ { /StatementList/ }
→ { /Statement/ }
→ { /LabelledStatement/ }
→ { /Identifier/ : /Statement/ }
→ { /Identifier/ : /ExpressionStatement/ }
→ { /Identifier/ : /Expression/ }
→ { /Identifier/ : /AssignmentExpression/ }
→ ...
→ { /Identifier/ : /Literal/ }
→ { /Identifier/ : /StringLiteral/ }
And the result of a /Program/ is the result of the evaluation of its
/SourceElements/. [ES3F, 15.1.2.1, 14 pp.]
A simple workaround is to put the supposed-to-be Object initializer in
parentheses -- eval('({key1:"value1"})'); -- which causes it to be parsed as
follows:
/Program/
→ /SourceElements/
→ /SourceElement/
→ /Statement/
→ /ExpressionStatement/
→ /Expression/
→ ( /Expression/ )
→ ...
→ ( /ObjectLiteral/ )
A less simple and more expensive workaround -- but I have seen it before --
is using brackets:
/Program/
→ /SourceElements/
→ /SourceElement/
→ /Statement/
→ /ExpressionStatement/
→ /Expression/
→ ...
→ /ArrayLiteral/
→ [ /ElementList/ ]
→ [ /AssignmentExpression/ ]
→ ...
→ [ /ObjectLiteral/ ]
And
var obj = eval( '{"key1":"value1"}' );
// syntax error "invalid label"
?
Since the string value of eval() is parsed as a /Program/, what looks like
an /ObjectLiteral/ at first is in fact parsed as a /Block/ statement, and
`"key1"' does not satisfy the criteria for a label since it needs to be an
/Identifier/:
/Program/
→ /SourceElements/
→ /SourceElement/
→ /Statement/
→ /Block/
→ { /StatementList/ }
→ { /Statement/ }
→ { /LabelledStatement/ }
→ { /Identifier/ : /Statement/ }
(→ Syntax error)
[ES3F, 15.1.2.1 pp.]
And
var obj = eval('{"key1":"value1", "key2" : "value2"}');
// syntax error "invalid label"
?
(Granted, this one is a bit tricky.)
The comma is not parsed as delimiter between name-value pairs in an Object
initializer, but as a comma operator here. `"key1":"value"' must be parsed
as a /LabelledStatement/, and `"key1"' does not satisfy the criteria for a
label since it needs to be an /Identifier/:
/Program/
→ /SourceElement/
→ /Statement/
→ /Block/
→ { /StatementList/ }
→ { /StatementList/ /Statement/ }
→ { /Statement/ /Statement/ }
→ { /LabelledStatement/ /LabelledStatement/ }
→ { /Identifier/ : /Statement/ /LabelledStatement/ }
→ { /Identifier/ : /ExpressionStatement/ /LabelledStatement/ }
→ { /Identifier/ : /Expression/ /LabelledStatement/ }
→ { /Identifier/ : /Expression/ , /AssignmentExpression/
/LabelledStatement/ }
(→ Syntax error)
[ES3F, 15.1.2.1, ..., 11.14]
If the productions following `/LabelledStatement/ /LabelledStatement/' are
correct (the productions until that undoubtedly are), then the second syntax
error, at the second /LabelledStatement/, is ignored.
And so on? I did over last hours more than planned for the week -
If you only tried to understand how the parser and grammar works, if you
only read the relevant parts of the Specification once, you would
understand; but then again, given your record of making up stories to fit
your arguments instead, probably not even then.
PointedEars