6

Recently I found out that this is completely valid:

1..toString();  //"1"

To me it looks a little bit weird in the first place, but with further explorations I figured out that it works is because the browser treats the first 1. as a number.

This leads us to the question. If I call .toString on a number:

1.toString();  //SyntaxError

it won't work. However, if I do:

1.0.toString(); /*or*/ 1..toString();  //"1"

it works.

Why is there a difference between 1 and 1.0? I thought there is no number types in JavaScript? Why would the decimal point matter?

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247

3 Answers3

2

It does not have much to do with the type of 1 or 1.0 but with the way lexer parses your code. A period following a string of digits is treated as a decimal point and not as the class member access (.) operator.

Enclosing 1 in parentheses solves the problem:

(1).toString();
peteykun
  • 716
  • 9
  • 21
2

You get the syntax error because 1.toString() is trying to call toString() on a floating point value but without using the dot access operator.

Whatever is interpreting that '.' has to decide whether it is there as a floating point indication or the access operator. Vagueties are not good, so one of those possibilities takes precedence. And in JavaScript's case, the floating point indicator is taking precedence (as described by peteykun in their answer, the lexer determines which code characters are considered part a number).

1..toString() and 1.0.toString() work because the floating point is already there so there is no uncertainty. We know then, that the second '.' has to be the access operator.

Rudi Kershaw
  • 12,332
  • 7
  • 52
  • 77
1

The parser expects a number followed by a dot (e.g. 1.) to be a floating point literal. This is why 1.toString() doesn't work

The following should work however (1).toString();

Ian A
  • 5,622
  • 2
  • 22
  • 31