调用数字字面量的成员函数

IT技术 javascript
2021-01-17 11:06:04

我试图调用文字函数,但我得到了奇怪的行为。

考虑这个返回true.

   23 === (23)

当我写尝试以下。

(23).toFixed(2)

我得到了预期的结果,_23.00_但是当我尝试时出现23.toFixed(2)此错误。

语法错误:意外的令牌非法

JavaScript 如何评估无法理解这一点的表达式,为什么会出现此错误?

3个回答

Greg Hewgillicktoofay的答案在所有方面都是正确的,但是,我想从抽象的角度讲一点:让我们看看根据 javascript 规范真正发生了什么。

规范的第 7.8.3 节定义了数字文字。我们可以看到以下内容:

DecimalLiteral ::
    DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt)
    . DecimalDigits ExponentPart(opt)
    DecimalIntegerLiteral ExponentPart(opt)

DecimalIntegerLiteral ::
    0 
    NonZeroDigit DecimalDigits(opt)

A DecimalLiteral,一个数字,是一堆十进制数字,可能后跟一个点,可能后跟其他数字(例如,所有数字都可以后跟指数e12)。换句话说,42.合法且等于423e2等于300

请注意,如果我们有一个点,我们要么期望它后面跟着更多的数字/指数,要么后面什么也不跟着。然而,这是重要的部分,点是数字的一部分请记住这一点,因为我们开始查看点运算符obj.prop, 是如何处理的。

第 11.2.1 节,属性访问器描述了成员访问的点和括号表示法:

MemberExpression . IdentifierName

CallExpression用于函数调用,我们不关心。请注意我们如何期待 a MemberExpression(它可以是 a DecimalLiteral- 但不要相信我的话,看看我是否正确)。

看到那个小点了吗?跳到前面说“好吧,这里的方案中有一个点4.foo……还有一个点……那么为什么会出现错误?”是合乎逻辑的唉,我在这些句子中使用的假设朋友,你忘记了它的DecimalLiteral样子!让我们回顾两个例子,看看会发生什么。

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

当然,还有其他几种方法可以将点与数字分开。正如您所展示的,一种方法是将文字括在括号中:(42).foo. 当我们到达括号末尾时,我们就离开了MemberExpression, 并且在点上。另一种方法是插入一个空格: 42 .foo,因为空格不能是数字的一部分,而且它对解析器来说是中性的,所以它不会引发错误。

与 Ruby(例如)不同,Javascript 解析器将.后面的数字视为数字的一部分。所以解析器看到令牌:

23. toFixed ( 2 )

这是一个语法错误,因为toFixed紧跟浮点数的单词没有意义。接受此语法的语言(例如 Ruby)将看到以下标记:

23 . toFixed ( 2 )

考虑:

5.

那是浮点文字5.还是5后跟一个点的整数你不知道;这是模棱两可的。JavaScript 采取前一种观点。在 JavaScript 看来,您有一个浮点文字后跟一个标识符(后跟一个左括号、数字和一个右括号)。

有些人通过使用两个点来解决这个问题:

23..toFixed(2)

由于浮点文字只能有一个小数点,因此另一个点是文字点标记。