18

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?

Peter Olson
  • 139,199
  • 49
  • 202
  • 242
  • 1
    note that the problem only arises with integer literals- a decimal is happy to call any methods. 3.14.toFixed(2). – kennebec Feb 21 '12 at 15:36
  • @kennebec Good point, I edited the question title to say integer instead of number. – Peter Olson Feb 21 '12 at 15:37
  • 1
    related, if not duplicate: [Why don't number literals have access to Number methods?](http://stackoverflow.com/q/4046342/1048572) – Bergi Feb 28 '16 at 10:40
  • 2
    Possible duplicate of [Calling member function of number literal](https://stackoverflow.com/questions/18555853/calling-member-function-of-number-literal), as the older [Usage of toString in JavaScript](https://stackoverflow.com/q/6853865/4642212) is also closed as a duplicate of it, but this question and the other ones are not linked so far. – Sebastian Simon Jan 17 '19 at 13:39

5 Answers5

22

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)
Peter Olson
  • 139,199
  • 49
  • 202
  • 242
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
12

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.

Rodney Folz
  • 6,709
  • 2
  • 29
  • 38
5

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.

ruakh
  • 175,680
  • 26
  • 273
  • 307
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.

georg
  • 211,518
  • 52
  • 313
  • 390
0

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()

Pavan
  • 632
  • 5
  • 9