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 NumberLiterals here, just because there's actually not very much demand for things like 3.foo.