Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The answers by <a href="https://stackoverflow.com/a/18555864">Greg Hewgill</a> and <a href="https://stackoverflow.com/a/18555871">icktoofay</a> are correct in all ways, however, I'd like to get down a bit, abstraction-wise: Let's see what's really happening according to the javascript specification.</p> <p><a href="http://es5.github.io/#x7.8.3" rel="nofollow noreferrer">Section 7.8.3</a> of the spec defines numeric literals. We can see the following:</p> <pre><code>DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt) . DecimalDigits ExponentPart(opt) DecimalIntegerLiteral ExponentPart(opt) DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigits(opt) </code></pre> <p>A <code>DecimalLiteral</code>, a number, is a bunch of decimal digits, possibly followed by a dot, which is possibly followed by other digits (all of which can be followed by an exponent, <code>e12</code> for instance). In other words, <code>42.</code> is legal and equal to <code>42</code> and <code>3e2</code> is equal to <code>300</code>.</p> <p>Note how if we have a dot, we either expect it to be followed by more digits/exponent, or be followed by nothing. However, and this is the important part, <em>the dot is part of the number</em>. Remember this as we move to look how the dot operator, <code>obj.prop</code>, is dealt with.</p> <p><a href="http://es5.github.io/#x11.2.1" rel="nofollow noreferrer">Section 11.2.1, Property Accessors</a> describes the dot and bracket notation for member access:</p> <pre><code>MemberExpression . IdentifierName </code></pre> <p><code>CallExpression</code> is for function calls, which we don't care about. Notice how we're expecting a <code>MemberExpression</code> (which can be a <code>DecimalLiteral</code> - but don't take my word for it, look and see whether I'm right).</p> <p>See that little dot? It's logical to jump forward and say "well, there's a dot in the scheme here...and there's a dot in <code>4.foo</code>...so why is there an error?" Alas my hypothetical friend whom I use for these sentences, you forgot how the <code>DecimalLiteral</code> looks like! Let's go over two examples and see what happens.</p> <pre><code>42.foo ^ </code></pre> <p>The caret represents the character we're on. So far, we're inside <code>DecimalLiteral / DecimalIntegerLiteral / NonZeroDigit</code> (that's quite a mouthful). Let's move to the next character:</p> <pre><code>42.foo ^ </code></pre> <p>Still part of the number, a perfectly valid <code>DecimalDigit</code>.</p> <pre><code>42.foo ^ </code></pre> <p>ok, so we're out of the <code>DecimalIntegerLiteral</code> part. Here's the same diagram on the scheme:</p> <pre><code>DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt) ^ </code></pre> <p>So we're on a dot, which is a perfectly valid part of a number. Now we consume it, <em>as part of the number</em>, and move on:</p> <pre><code>42.foo ^ </code></pre> <p><code>f</code> is neither part of <code>DecimalDigits</code> nor of <code>ExponentPart</code>, we're out of the number now. So...what now? What's that <code>f</code>? It's not part of anything. Maybe it's a property accessor? Let's take a look at the scheme:</p> <pre><code>MemberExpression . IdentifierName ^ </code></pre> <p>We're definitely on <code>MemberExpression</code>, but we don't have a dot which follows it - that dot is already part of the number. We've reached a syntactical error: we stop execution and throw it. Hopefully you don't live in a glass house.</p> <p>Hopefully now you understand why <code>42..foo</code> works. Once we're out of the <code>MemberExpression</code>, we face another dot:</p> <pre><code> 42..foo ^ MemberExpression . IdentifierName ^ </code></pre> <p>Followed by a perfectly legal <code>IdentifierName</code>.</p> <p>Of course, there're several other ways to separate the dot from the number. One way, as you showed, is to surround the literal in parentheses: <code>(42).foo</code>. When we've reached the parentheses end, we're out of the <code>MemberExpression</code>, and on the dot. Another way is to insert a space: <code>42 .foo</code>, since a space can't be part of the number, and it's neutral for the parser, so it won't raise an error.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload