Why are some object-literal properties quoted and others not? [duplicate] - javascript

This question already has answers here:
What is the difference between object keys with quotes and without quotes?
(5 answers)
Closed 9 years ago.
I see this all the time: object literals declared such that some keys are surrounded with quotes and others are not. An example from jQuery 1.4.2:
jQuery.props = {
"for": "htmlFor",
"class": "className",
readonly: "readOnly",
maxlength: "maxLength",
cellspacing: "cellSpacing",
rowspan: "rowSpan",
colspan: "colSpan",
tabindex: "tabIndex",
usemap: "useMap",
frameborder: "frameBorder"
};
What is the significance of wrapping the first two property keys (for and class) with quotes, while leaving the others quote-less? Are there any differences at all?
I've been poking around the ECMAScript 5 specification; all I've been able to find is [Note 6 of Section 15.12.3, emphasis mine]:
NOTE 6 An object is rendered as an
opening left brace followed by zero or
more properties, separated with
commas, closed with a right brace. A
property is a quoted String
representing the key or property name,
a colon, and then the stringified
property value. An array is rendered
as an opening left bracket followed by
zero or more values, separated with
commas, closed with a right bracket.
However, this refers only to the stringification of JSON.

Those are Javascript reserved words, and (though not really necessary) the syntax of the language requires that they be quoted.
Strictly speaking, pure "JSON" notation requires that all of the "key" strings be quoted. Javascript itself however is OK with keys that are valid identifiers (but not reserved words) being unquoted.

There is a reason at this point (two plus years later) to quote object literal properties. If one wants to minify their code using the Closure Compiler they may need to make the properties accessible to other source files. In that case, they will want to avoid having symbols renamed by the compiler. By quoting the property name, the Closure Compiler will not minify (rename) them.
See: Removal of code you want to keep
(This applies to at least the ADVANCED_OPTIMIZATIONS setting.)

Javascript language keywords or reserved keywords are always surrounded by quotes in there.

for and class are language keywords. Your interpreter would throw a SyntaxError when those are unquoted.
See section 7.6.1.1 in the Spec you linked to.

Javascript has a lot of reserved words that are not actually used by the language which I think were reserved for possible future use. class is one of these even though Javascript does not actually use classes. Another is goto and there's absolutely no chance of that ever being used. The result, however, is that if you want to use these as a json key then it has to be quoted. Strictly speaking you should probably always quote your keys just to avoid the possibility of falling foul of the javascript unused reserved word trap (mind you - I never do).

Related

Accessing object key with dot notation and space

I came across the following:
var object = {};
object.name = 'ABC';
console.log(object. name); // this is still valid
Notice the space after object.
Why is this valid? Is there any ECMA specification for this?
Same is true for all the inherited properties for different data types.
I've tested this on a node terminal.
Thanks!
Why is this valid?
Because whitespace is largely (though not entirely) irrelevant in the JavaScript syntax. You can safely insert any whitespace other than a line break between two tokens (and in most, but not all cases, you can insert line breaks as well; the "most" is due to ASI). You can't insert spaces within tokens (because it breaks them up into two tokens), but you can between tokens.
As Federico klez Culloca points out (link), . is an operator, just like + or *. The fact we generally don't put spaces around it, but do put spaces around them, is simply convention.
These are all valid:
console.log(object.name);
console.log(
object.name
);
console.log(
object . name
);
console.log(
object
.
name
);
Is there any ECMA specification for this?
Of course, the specification itself. Specifically here and here. From that last link:
Input elements other than white space and comments form the terminal symbols for the syntactic grammar for ECMAScript and are called ECMAScript tokens. These tokens are the reserved words, identifiers, literals, and punctuators of the ECMAScript language. Moreover, line terminators, although not considered to be tokens, also become part of the stream of input elements and guide the process of automatic semicolon insertion (11.9). Simple white space and single-line comments are discarded and do not appear in the stream of input elements for the syntactic grammar.

Why does a number inside parentheses have methods, but a number outside parentheses does not? [duplicate]

If I try to write
3.toFixed(5)
there is a syntax error. Using double dots, putting in a space, putting the three in parentheses or using bracket notation allows it to work properly.
3..toFixed(5)
3 .toFixed(5)
(3).toFixed(5)
3["toFixed"](5)
Why doesn't the single dot notation work and which one of these alternatives should I use instead?
The period is part of the number, so the code will be interpreted the same as:
(3.)toFixed(5)
This will naturally give a syntax error, as you can't immediately follow the number with an identifier.
Any method that keeps the period from being interpreted as part of the number would work. I think that the clearest way is to put parentheses around the number:
(3).toFixed(5)
You can't access it because of a flaw in JavaScript's tokenizer. Javascript tries to parse the dot notation on a number as a floating point literal, so you can't follow it with a property or method:
2.toString(); // raises SyntaxError
As you mentioned, there are a couple of workarounds which can be used in order make number literals act as objects too. Any of these is equally valid.
2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first
To understand more behind object usage and properties, check out the Javascript Garden.
It doesn't work because JavaScript interprets the 3. as being either the start of a floating-point constant (such as 3.5) or else an entire floating-point constant (with 3. == 3.0), so you can't follow it by an identifier (in your case, a property-name). It fails to recognize that you intended the 3 and the . to be two separate tokens.
Any of your workarounds looks fine to me.
This is an ambiguity in the Javascript grammar. When the parser has got some digits and then encounters a dot, it has a choice between "NumberLiteral" (like 3.5) or "MemberExpression" (like 3.foo). I guess this ambiguity cannot be resolved by lookahead because of scientific notation - should 3.e2 be interpreted as 300 or a property e2 of 3? Therefore they voluntary decided to prefer NumberLiterals here, just because there's actually not very much demand for things like 3.foo.
As others have mentioned, Javascript parser interprets the dot after Integer literals as a decimal point and hence it won't invoke the methods or properties on Number object.
To explicitly inform JS parser to invoke the properties or methods on Integer literals, you can use any of the below options:
Two Dot Notation
3..toFixed()
Separating with a space
3 .toFixed()
Write integer as a decimal
3.0.toFixed()
Enclose in parentheses
(3).toFixed()
Assign to a constant or variable
const nbr = 3;
nbr.toFixed()

How is "first-name" a reserved word in JavaScript?

Note: This question pertains to the book 'JavaScript: The Good Parts' written by Doug Crockford.
As I was reading a chapter on Objects, I came across a statement as follows:
The quotes around a property's name in an object literal are optional if the name would be a legal JavaScript name and not a reserved word. So quotes are required around "first-name", but are optional around "first_name".
And the following is the example of an object literal provided in the book:
var stooge = {
"first-name": "Jerome",
"last-name": "Howard"
};
Now, I might have misinterpreted the text here but to me it seems like Mr. Crockford is saying first-name (with the hyphen) IS a reserved word whereas first_name (with the underscore) is not. If that is the case, I don't understand how the former can be a reserved word. I found no other explanation in the book why this is. Can someone please explain?
It is not a reserved word. Without the quotes, javascript will interpret the - character as a subtraction operator, attempt to perform the operation, and fail.
One reason for this is that javascript prefers to ignore whitespace whenever it can. Thus 2 - 3 is the same as 2-3.
Putting the whole thing in quotes causes the js to interpret as just another character, not an operator.

Why can't I access a property of an integer with a single dot?

If I try to write
3.toFixed(5)
there is a syntax error. Using double dots, putting in a space, putting the three in parentheses or using bracket notation allows it to work properly.
3..toFixed(5)
3 .toFixed(5)
(3).toFixed(5)
3["toFixed"](5)
Why doesn't the single dot notation work and which one of these alternatives should I use instead?
The period is part of the number, so the code will be interpreted the same as:
(3.)toFixed(5)
This will naturally give a syntax error, as you can't immediately follow the number with an identifier.
Any method that keeps the period from being interpreted as part of the number would work. I think that the clearest way is to put parentheses around the number:
(3).toFixed(5)
You can't access it because of a flaw in JavaScript's tokenizer. Javascript tries to parse the dot notation on a number as a floating point literal, so you can't follow it with a property or method:
2.toString(); // raises SyntaxError
As you mentioned, there are a couple of workarounds which can be used in order make number literals act as objects too. Any of these is equally valid.
2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first
To understand more behind object usage and properties, check out the Javascript Garden.
It doesn't work because JavaScript interprets the 3. as being either the start of a floating-point constant (such as 3.5) or else an entire floating-point constant (with 3. == 3.0), so you can't follow it by an identifier (in your case, a property-name). It fails to recognize that you intended the 3 and the . to be two separate tokens.
Any of your workarounds looks fine to me.
This is an ambiguity in the Javascript grammar. When the parser has got some digits and then encounters a dot, it has a choice between "NumberLiteral" (like 3.5) or "MemberExpression" (like 3.foo). I guess this ambiguity cannot be resolved by lookahead because of scientific notation - should 3.e2 be interpreted as 300 or a property e2 of 3? Therefore they voluntary decided to prefer NumberLiterals here, just because there's actually not very much demand for things like 3.foo.
As others have mentioned, Javascript parser interprets the dot after Integer literals as a decimal point and hence it won't invoke the methods or properties on Number object.
To explicitly inform JS parser to invoke the properties or methods on Integer literals, you can use any of the below options:
Two Dot Notation
3..toFixed()
Separating with a space
3 .toFixed()
Write integer as a decimal
3.0.toFixed()
Enclose in parentheses
(3).toFixed()
Assign to a constant or variable
const nbr = 3;
nbr.toFixed()

Javascript object property quotes [duplicate]

This question already has answers here:
What is the difference between object keys with quotes and without quotes?
(5 answers)
Closed 5 years ago.
Let's say I have the following object:
var VariableName = {
firstProperty: 1,
secondProperty: 2
}
Do I have to wrap the object properties in quotes like this?
var VariableName = {
'firstProperty': 1,
'secondProperty': 2
}
Is this Single quotes in JavaScript object literal the correct answer?
No, you don't need to do that.
The only reasons to quote object-keys are
the property name is reserved/used by the browser/js engine (eg. "class" in IE)
you have special characters or white spaces in your key
so for instance
var VariableName = {
"some-prop": 42, // needs quotation because of `-`
"class": 'foobar' // doesn't syntatically require quotes, but it will fail on some IEs
valid: 'yay' // no quotes required
};
You only have to use the quotes around the property, if the property name is a reserved word (like for, in, function, ...). That way you prevent Javascript from trying to interpret the keyword as a part of the language and most probably get a syntax error.
Furthermore, if you want to use spaces in property names, you also have to use quotes.
If your property names are just normal names without any collusion potential or spaces, you may use the syntax you prefer.
One other possibility that requires quotes is the use of Javascript minifiers like google closure compiler, as it tends to replace all property names. If you put your property names in quotes, however, the closure compiler preserves the property as you coded it. This has some relevance when exporting objects in a library or using an parameter object.
Property names in object literals must be strings, numbers or identifiers. If the name is a valid identifier, then you don't need quotes, otherwise they follow the same rules as strings.
firstProperty and secondProperty are both valid identifiers, so you don't need quotes.
See page 65 of the specification for more details.
For Javascript you usually do not have to use quotes. You may use ' or " if you like, and you must use quotes if there is a clash between the name of your property and a JS reserved word like null. The answer you linked to seems to be correct, yes.
For JSON, you should use " around strings (including object property names)

Categories

Resources