Greg Hewgillとicktoofayの回答はすべて正しいですが、私はちょっと抽象的な言い方をしておきたいと思います。実際にjavascriptの仕様に従って何が起こっているのか見てみましょう。
Section 7.8.3は、数値リテラルを定義します。我々は次のことを見ることができます:
DecimalLiteral ::
DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt)
. DecimalDigits ExponentPart(opt)
DecimalIntegerLiteral ExponentPart(opt)
DecimalIntegerLiteral ::
0
NonZeroDigit DecimalDigits(opt)
DecimalLiteral
、数は、おそらく可能性指数が続くことができる他の数字(全てが続いている点、続いて、桁の束であり、例えばe12
)。換言すれば、42.
は合法であり、42
に等しく、3e2
は300
に等しい。
ドットがある場合は、数字/指数のほうが後ろに来るか、何も続きないことに注意してください。しかし、これは重要な部分です。ドットは番号の一部です。これを覚えておくと、ドット演算子obj.prop
がどのように処理されているかを見ていきます。
Section 11.2.1, Property Accessorsは、メンバーアクセスのためのドットとブラケット表記法について説明します。
MemberExpression . IdentifierName
CallExpression
は、我々は気にしない関数呼び出し、ためです。 MemberExpression
(これはDecimalLiteral
でもかまいませんが、私の言葉を取って、見て、私が正しいかどうかはわかりません)を期待しています。
小さなドットを参照してください。 「ここにスキームにドットがあります。4.foo
にドットがあります...なぜ、エラーがあるのですか?」私がこれらの文章のために使っている私の仮説的な友人のように、DecimalLiteral
の様子を忘れてしまった! 2つの例を見て、何が起こるか見てみましょう。
42.foo
^
キャレットは、現在のキャラクターを表します。これまでのところ、私たちはDecimalLiteral/DecimalIntegerLiteral/NonZeroDigit
の中にいます(それはかなり口が開いています)。それでも
42.foo
^
数、完全に有効なDecimalDigit
の一部:のは、次の文字に移動しましょう。
42.foo
^
okですので、私たちはDecimalIntegerLiteral
部分を使い果たしています。スキームに関する同じダイアグラムは次のとおりです。
DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt)
^
これは数字の完全な有効部分です。今、私たちは数の一環として、それを消費し、上の移動:
42.foo
^
f
はDecimalDigits
のもExponentPart
のどちらも一部であり、我々は今、数の出ています。ならどうしよう?それは何ですか。f
?それは何の一部でもありません。たぶんそれはプロパティのアクセサーですか?スキームを見てみましょう:
MemberExpression . IdentifierName
^
我々はMemberExpression
に間違いだが、我々はそれを次の点がありません - ドットは、すでに数の一部であることを。文法上のエラーに達しました。実行を停止してスローします。うまくいけば、あなたはガラスの家に住んでいないことを望みます。
うまくいけば、なぜ42..foo
が機能するのかを理解してください。
42..foo
^
MemberExpression . IdentifierName
^
完全に合法IdentifierName
続く:私たちはMemberExpression
の出ているならば、我々は別のドットに直面しています。
もちろん、ドットと数字を区別する方法はいくつかあります。あなたが示したように、1つの方法は、リテラルを括弧で囲むことです:(42).foo
。カッコが終わったら、MemberExpression
とドットの外に出ています。もう1つの方法は、空白を数値の一部にすることはできず、パーサーにとっては中立であるため、エラーを発生させないために、スペースを挿入することです(42 .foo
)。
優秀な回答! –