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?
Solution 1:
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)
Solution 2:
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.
Solution 3:
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.
Solution 4:
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 NumberLiteral
s here, just because there's actually not very much demand for things like 3.foo
.