Greg Hewgillとicktoofayによる回答はすべての点で正しいですが、抽象化に関して少し掘り下げたいと思います。JavaScript の仕様に従って実際に何が起こっているか見てみましょう。
仕様のセクション 7.8.3では、数値リテラルが定義されています。次のことがわかります。
DecimalLiteral ::
DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt)
. DecimalDigits ExponentPart(opt)
DecimalIntegerLiteral ExponentPart(opt)
DecimalIntegerLiteral ::
0
NonZeroDigit DecimalDigits(opt)
A DecimalLiteral
、数値は、10 進数の数字の集まりであり、その後にドットが続く可能性があり、その後に他の数字が続く可能性があります (たとえば、すべての後に指数が続く可能性がありe12
ます)。言い換えると、42.
は合法であり、 に等しく、 に42
等しい3e2
です300
。
ドットがある場合、その後にさらに数字/指数が続くか、何も続かないと予想されることに注意してください。ただし、これは重要な部分です。ドットは数字の一部です。ドット演算子 がどのようにobj.prop
扱われるかを見ていく際に、このことを思い出してください。
セクション 11.2.1, プロパティ アクセサーでは、メンバー アクセスのドットとブラケットの表記について説明しています。
MemberExpression . IdentifierName
CallExpression
気にしない関数呼び出し用です。どのように a が期待されているかに注意してくださいMemberExpression
(これは a である可能性がありますがDecimalLiteral
、私の言葉を鵜呑みにしないでください。私が正しいかどうかを見てください)。
あの小さな点が見えますか?4.foo
先に進んで、「ここのスキームにドットがあります...そしてドットがあります...では、なぜエラーがあるのでしょうか?」と言うのは論理的です。悲しいかな、私がこれらの文で使用している架空の友人ですが、あなたは がどのようにDecimalLiteral
見えるか忘れてしまいました! 2 つの例を見て、何が起こるか見てみましょう。
42.foo
^
キャレットは、現在の文字を表します。これまでのところ、私たちは中にいますDecimalLiteral / DecimalIntegerLiteral / NonZeroDigit
(それはかなり一口です)。次のキャラクターに移りましょう。
42.foo
^
まだ番号の一部であり、完全に有効なDecimalDigit
.
42.foo
^
よし、これで本題から外れるDecimalIntegerLiteral
。スキームの同じ図を次に示します。
DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt)
^
これは、数値の完全に有効な部分です。これをnumber の一部として消費し、先に進みます。
42.foo
^
f
DecimalDigits
は の一部でも の一部でもありませんExponentPart
。現在、数が不足しています。ならどうしよう?それは何f
ですか?それは何の一部でもありません。多分それはプロパティアクセサーですか?スキームを見てみましょう:
MemberExpression . IdentifierName
^
間違いなく ですMemberExpression
が、それに続くドットはありません。そのドットはすでに数字の一部です。構文エラーに達しました: 実行を停止してスローします。ガラスの家に住んでいないことを願っています。
うまくいけば、なぜ42..foo
機能するのか理解できます。を抜けると、MemberExpression
別の点に直面します。
42..foo
^
MemberExpression . IdentifierName
^
完全に合法的な が続きIdentifierName
ます。
もちろん、数字からドットを分離する方法は他にもいくつかあります。あなたが示したように、1つの方法は、リテラルを括弧で囲むことです: (42).foo
. かっこの終わりに到達すると、 , から抜け出し、MemberExpression
点に着きます。もう 1 つの方法は、スペースを挿入することです: 42 .foo
、スペースは数値の一部にすることはできず、パーサーにとってニュートラルであるため、エラーは発生しません。