我正在尝试调用文字函数,但出现奇怪的行为。
考虑下面返回的代码true。
true
23 === (23)
当我写的时候尝试以下方法。
(23).toFixed(2)
我得到了预期的结果,_23.00_但是当我尝试时出现23.toFixed(2)此错误。
_23.00_
23.toFixed(2)
语法错误:意外的令牌非法
JavaScript如何评估无法理解的表达式,为什么会出现此错误?
DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt) . DecimalDigits ExponentPart(opt) DecimalIntegerLiteral ExponentPart(opt)
DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigits(opt)
A DecimalLiteral(一个数字)是一串十进制数字,可能跟一个点,然后可能跟着其他数字(例如,所有这些都可以跟一个指数e12)。换句话说,42.是合法的,等于42和3e2等于300。
DecimalLiteral
e12
42.
42
3e2
300
请注意,如果我们有一个点,我们希望它后面跟着更多数字/指数,或者什么都不跟。但是,这是重要的部分, 点是数字的一部分 。记住这一点,因为我们开始研究如何处理点运算符obj.prop。
obj.prop
第11.2.1节“属性访问器”描述了成员访问的点和括号符号:
MemberExpression . IdentifierName
CallExpression是函数调用,我们不在乎。请注意,我们期望的是MemberExpression(可能是DecimalLiteral-,但请不要相信我,看一下我是否正确)。
CallExpression
MemberExpression
看到那个小点吗?向前跳并说“好吧,这里的方案中有一个点……而其中有一个点4.foo……那么为什么会有错误?”是合乎逻辑的。my,我在这些句子中使用的假想朋友,您忘记了DecimalLiteral样子!让我们看两个例子,看看会发生什么。
4.foo
42.foo ^
尖号代表我们所处的角色。到目前为止,我们在里面DecimalLiteral / DecimalIntegerLiteral / NonZeroDigit(这是一个很大的入口)。让我们转到下一个字符:
DecimalLiteral / DecimalIntegerLiteral / NonZeroDigit
仍然是数字的一部分,完全有效DecimalDigit。
DecimalDigit
好的,所以我们不DecimalIntegerLiteral参加了。这是该方案的同一图:
DecimalIntegerLiteral
DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt) ^
所以我们在一个点上,这是一个数字的完全有效部分。现在,我们将其 作为数字的一部分使用 ,然后继续:
f既不是DecimalDigits也不是的一部分ExponentPart,我们现在已经不存在了。所以现在怎么办?那是f什么 它不是任何东西的一部分。也许是物业访问者?让我们看一下该方案:
f
DecimalDigits
ExponentPart
MemberExpression . IdentifierName ^
我们肯定在MemberExpression,但是我们没有在其后的点- 该点已经是数字的一部分。我们遇到了语法错误:我们停止执行并抛出错误。希望你不要住在玻璃屋里。
希望现在您了解为什么42..foo有效。一旦离开MemberExpression,我们将面临另一个圆点:
42..foo
42..foo ^ MemberExpression . IdentifierName ^
其次是完全合法的IdentifierName。
IdentifierName
当然,还有其他几种方法可以将点与数字分开。如您所展示,一种方法是将文字括在括号中:(42).foo。当我们到达圆括号的末端时,我们就不在了,而是在MemberExpression圆点上。另一种方法是插入一个空格:42.foo,因为空格不能成为数字的一部分,并且对于解析器而言是中立的,所以不会引发错误。
(42).foo
42.foo