The answers of Greg Hewgill and icktoofay are true in every way, however I would like to go down a bit, abstract myself: let's see what actually happens according to the javascript specification.
Section 7.8.3 of the specification defines numeric literals. We can see the following:
DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt) . DecimalDigits ExponentPart(opt) DecimalIntegerLiteral ExponentPart(opt) DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigits(opt)
A DecimalLiteral , a number is a group of decimal digits, possibly followed by a period, possibly followed by other digits (which can be followed, for example, by the exponent e12 ). In other words, 42. is legal and is 42 , and 3e2 is 300 .
Please note that if we have a dot, we either expect that it will be followed by a larger number of digits / exhibitors, or nothing will follow. However, and this is an important part, the dot is part of the number. Keep this in mind when we move on to examining how the point operator, obj.prop , is obj.prop .
Section 11.2.1, Property Accessors, describes the notation of dots and brackets for member access:
MemberExpression . IdentifierName
CallExpression designed to call functions that we do not need. Please note that we are expecting MemberExpression (which may be DecimalLiteral - but don't take my word for it, look and make sure I'm right).
See this little dot? It is logical to jump forward and say "well, there is a point in the circuit here ... and there is a point in 4.foo ... so why is there an error?" Alas, my hypothetical friend whom I use for these offers, you forgot what DecimalLiteral looks DecimalLiteral ! Let's move on to two examples and see what happens.
42.foo ^
The carriage represents the symbol in which we are. So far, we are inside DecimalLiteral / DecimalIntegerLiteral / NonZeroDigit (that's quite a lot). Go to the following symbol:
42.foo ^
Still part of the number, perfectly correct DecimalDigit .
42.foo ^
ok, so we left the DecimalIntegerLiteral part. Here is the same diagram in the diagram:
DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt) ^
So, we are at the point, which is a very real part of the number. Now we consume it, as part of the number, and move on:
42.foo ^
f is neither part of DecimalDigits nor ExponentPart , now we are behind the number. And now what? What is this f ? This is not part of anything. Maybe this is an access property? Let's look at the diagram:
MemberExpression . IdentifierName ^
We are definitely on MemberExpression , but we donβt have a dot that follows it β that dot is already part of the number. We have reached a syntax error: we stop execution and throw it. I hope you do not live in a glass house.
Hopefully now you will understand why 42..foo works. When we MemberExpression , we will MemberExpression another point:
42..foo ^ MemberExpression . IdentifierName ^
What follows is a perfectly legitimate IdentifierName .
Of course, there are several other ways to separate a point from a number. One way, as you have shown, is to surround literal parentheses: (42).foo . When we reached the end of the parentheses, we left MemberExpression and point. Another way is to insert a space: 42 .foo , since space cannot be part of a number, and it is neutral for the parser, so it does not cause an error.