Prev: Are arguments that are objects passed by reference?
Next: FAQ Topic - How do I access a frame's content? (2009-10-25)
From: Lasse Reichstein Nielsen on 24 Oct 2009 17:55 VK <schools_ring(a)yahoo.com> writes: > On the topic and if you manage to fight over the regular "get VK!" > instincts than you see that: > > { > a: "a", > b: "b" > } > is interpreted as a block with a and b label literals. If interpreted as a program or statement, yes. In that context, a "{" starts a statement block. > { > a: "a", > "b": "b" > } > is interpreted as a block with a and b label literals where b is > illegal as we cannot use string value instead of literal so syntax > error. Yes, the "{" starts a statement block, and the content is not a syntactically valid statement block. > var obj = { > a: "a", > "b": "b" > } > creates the necessary interpretation context so the right part is > treated as an object constructor and the automatic quoting gets on, Not really. The "{" is in expression context, so it starts an object literal. The content is a valid object initializer, so yey, it works. The "automatic quoting" doesn't really exist. It's a completely different syntactic construct with different rules, that just happens to look almost the same. > so we may quote the keys, We may use string literals as keys. The difference between foo: 42 and "foo": 42 isn't that we quote anything, but that one is an identifier and the other is a string literal. Completely different syntactic categories, both valid at this particular point of an object initializer. > do not quote them or do quote them zebra-style > or whatever. Even if the very first key is not quoted, it is still > interpreted as key string value, because the "interpretation decision" > is being made before that. It's interpreted as an object key. > var obj = { > a: "a", > "default": "b" > } > absolutely the same as before, the "interpretation decision" is being > made before entering so it is already decided that it is an object > constructor and not a block of statements, so it is irrelevant that > the first key is not quoted: the quotes will be added automatically. No. No quotes are added. The identifier is parsed *as an identifier*. That identifier is converted to a string value (which takes no quoting). > var obj = { > a: "a", > default: "b" > } > the "interpretation decision" is being made before entering so it is > already decided that it is an object constructor and not a block of > statements, so it is irrelevant that the first key is not quoted: the > quotes will be added automatically; > THEN the system meets [default] chars sequence which corresponds to > one of reserved words in the parser list AND it changes its own > previous decision: now no, it is not a constructor but a block of > statements with the second one preceded by an illegal label literal. Not at all. This is parsed as an object initializer. There is no automatic quoting, and only string literals and identifiers are valid keys. Sadly "default" is a keyword, so it is not an identifier, which makes it a syntax error in the object initializer. There is no "automatic quoting". There is no "intepretation decission", only syntactic rules deciding whether a "{" may start a statement block or an object initializer. /L -- Lasse Reichstein Holst Nielsen 'Javascript frameworks is a disruptive technology'
From: VK on 24 Oct 2009 19:01 Lasse Reichstein Nielsen wrote: > We may use string literals as keys. The difference between > foo: 42 > and > "foo": 42 > isn't that we quote anything, but that one is an identifier and the other > is a string literal. Completely different syntactic categories, both > valid at this particular point of an object initializer. I think I am starting to see the mistake making by Richard and by you: or maybe and very probably not a mistake but some profound difference in the applied logic between of us, because - I agree in advance - my logic is too "special". If unquoted key is interpreted as identifier - in the identifier sense I am using for more than 10 years and to late to change I'm afraid : ( :) - then in case like var a = 'foo'; var obj1 = {a : 'bar'} var obj2 = {'a': 'bar'} obj1 and obj2 have to have different properties: 'foo' in the first case, 'a' in the second. In the reality both of them are having the same property 'a' I am really sorry but an "identifier" that is not get identified is not an identifier, and the whole ECMA 262 wisdom may not override it in my (stupid, stubborning, whatever) head.
From: Lasse Reichstein Nielsen on 24 Oct 2009 20:13 VK <schools_ring(a)yahoo.com> writes: > Lasse Reichstein Nielsen wrote: >> We may use string literals as keys. The difference between >> �foo: 42 >> and >> �"foo": 42 >> isn't that we quote anything, but that one is an identifier and the other >> is a string literal. Completely different syntactic categories, both >> valid at this particular point of an object initializer. > > I think I am starting to see the mistake making by Richard and by you: > or maybe and very probably not a mistake but some profound difference > in the applied logic between of us, because - I agree in advance - my > logic is too "special". > If unquoted key is interpreted as identifier - in the identifier sense > I am using for more than 10 years and to late to change I'm afraid : > ( :) - then in case like > > var a = 'foo'; > var obj1 = {a : 'bar'} > var obj2 = {'a': 'bar'} > > obj1 and obj2 have to have different properties: 'foo' in the first > case, 'a' in the second. In the reality both of them are having the > same property 'a' Here you fail to distinguish between an identifier and a variable. In ECMAScript syntax, an Identifier is a syntactic category. I.e., it denotes a sequence of characters. It is used in several different places where something can be given a name: A variable name, an object property name, a function name. The identifier specifies a name. It is not the thing it names. In your example, the identifier "a" is used twice: Once to identify a variable, and once to identify an object property. The two are not related. The use as a property name does not refer to the variable, nor is it evaluated to the variable's value. Consider this example: function a() { var a = {a: 42}; return a.a; } The identifier "a" is used five times, three times to name the function, the variable and the object property, and two times to reference the variable and the object property. > I am really sorry but an "identifier" that is not get identified is > not an identifier, and the whole ECMA 262 wisdom may not override it > in my (stupid, stubborning, whatever) head. In the case: var a = "foo"; function() { var a = "bar"; } would you expect the variable inside the function to be called "foo"? It's called "a" too, because a name *in a declaration* is not interpreted. It's the same for object initializers: They contain declarations of properties. The names are not interpreted, so: var a = "foo"; var b = {a : 42}; declares a property named "a" on an object, not "foo". /L -- Lasse Reichstein Holst Nielsen 'Javascript frameworks is a disruptive technology'
From: VK on 25 Oct 2009 05:57 Lasse Reichstein Nielsen wrote: > Consider this example: > function a() { > var a = {a: 42}; > return a.a; > } > The identifier "a" is used five times, three times to name the > function, the variable and the object property, and two times to > reference the variable and the object property. "VK's universe": identifier "a" is used two times: to name a function and to name function-level variable. As these entities are in different scopes we have no identifiers conflict. The third use is object property name with is implicit string value and not a relevant part of the test case. To have an identifiers conflict we obviously need to use them in the same scope, so to illustrate what was intended to be illustrated we need to place identifiers in the same scope: function a() {a=1;} // 1 function a() {a=2;} // 2 window.alert(a.toString()); // the 2dn one or a = 1; a = (a == a + a - a); window.alert(a); // true > In the case: > > var a = "foo"; > function() { > var a = "bar"; > } > > would you expect the variable inside the function to be called "foo"? "VK's universe": Of course not because the identified variables are in different scopes: the outer one (Global if this is the whole code of the script as posted) with value "foo" and the inner one (function level). > It's called "a" too, because a name *in a declaration* is not interpreted.. > It's the same for object initializers: They contain declarations of > properties. The names are not interpreted, so: > > var a = "foo"; > var b = {a : 42}; > > declares a property named "a" on an object, not "foo". "VK's universe": because object property name is a string one may skip quotes as they are implied. But in this case it has to conform with JavaScript naming rules for identifiers because the parser is optimized for the quickest code source parsing so it will not bother with each and every non-quoted literal context: it just checks that each non-quoted literal is either a number, or one of reserved values like true or null, or a valid JavaScript variable name. If neither it drops the parsing so do no waste the time. P.S. I seem to feel what you really tried to say by your samples. Something like "identifier <a> identifying property name "a" or something like that and I do agree that such interpretation is possible - but IMHO such level of abstraction is way too high to be practical.
From: VK on 25 Oct 2009 06:16
> "VK's universe": because object property name is a string one may skip > quotes as they are implied. But in this case it has to conform with > JavaScript naming rules for identifiers because the parser is > optimized for the quickest code source parsing so it will not bother > with each and every non-quoted literal context: it just checks that > each non-quoted literal is either a number, or one of reserved values > like true or null, or a valid JavaScript variable name. If neither it > drops the parsing so do no waste the time. And about the Gecko engine the answer from mozilla.dev.tech.js-engine just reminded me the old discussion here about the SpiderMonkey's particular treatment of reserved words: the parser keeps the list not all reserved words but only ones actually being in use by the current machine, so for Gecko browsers it is fully OK like: var class = 'foobar'; window.alert(class); // 'foobar' |