关键字和文字之间需要空格
Spaces required between keyword and literal
查看 UglifyJS2 的输出,我注意到文字和 in
运算符之间不需要 space(例如,'foo'in{foo:'bar'}
有效)。
然而,在使用 Chrome 的 DevTools 时,我注意到十六进制和二进制数字文字在 in
关键字之前需要一个 space:
Internet Explorer 对所有三个测试都返回 true,而 FireFox 48.0.1 对第一个测试抛出一个 SyntaxError (1in foo
),但是字符串文字是可以的 ('1'in foo==true
)。
似乎解析 JavaScript 应该没有问题,允许关键字紧挨着数字文字,但我在 ECMAScript 规范中找不到任何明确的规则(其中任何一个)。
进一步测试表明,Chrome 和 FireFox(IE11 不支持 for..of 循环)都允许像 for(var i of[1,2,3])...
这样的语句,并且 typeof"string"
在所有三个中都有效.
哪种行为是正确的?事实上,它是在我错过的某个地方定义的,还是所有这些效果都是每个浏览器解析器的特性造成的?
不是专家 - 我没有做过 JS 编译器,但做过其他的。
ecma-262.pdf有点模糊,但是很明显,像1 in foo
这样的表达式应该被解析为3个输入元素,都是token。每个token是一个CommonToken
(11.5);在这种情况下,我们得到 numericLiteral
、identifierName
(是的,in
是一个 identifierName
)和 identifierName
。解析 0b1 in foo
时也是如此(见 11.8.3).
那么,当你取出 WS 时会发生什么?它没有明确涵盖(据我所知),但它是编写词法分析器扫描最长字符序列(可能与您可能正在寻找的内容匹配)时的常见做法(在其他语言中)。第 11 节的介绍几乎完全是这样说的:
The source text is scanned from left to right, repeatedly taking the
longest possible sequence of code points as the next input element.
因此,对于 0b1in foo
,词法分析器经过 0b1
,它匹配一个数字文字,然后到达 i
,给出 0b1i
,它不匹配任何东西.因此它将最长的匹配项 (0b1
) 作为标记传递给解析器的其余部分,并在 i
处再次开始。它找到 n
,然后是 WS,因此将 in
作为第二个标记传递,依此类推。
所以,基本上,奇怪的是,IE 看起来是正确的。
TL;DR
如果在这些情况下不需要空格,代码的解释方式将不会发生变化,但它是规范的一部分。
查看 source code of v8 that handles number literal parsing, it cites ECMA 262 § 7.8.3:
The source character immediately following a NumericLiteral must not be an IdentifierStart or DecimalDigit.
NOTE For example:
3in
is an error and not the two input elements 3 and in.
这部分似乎与第7部分的介绍相矛盾。但是,打破该规则并允许解析3in
似乎不会有任何问题。在某些情况下,文字和标识符之间不允许有空格会改变源代码的解析方式,但所有情况只会改变生成的错误。
查看 UglifyJS2 的输出,我注意到文字和 in
运算符之间不需要 space(例如,'foo'in{foo:'bar'}
有效)。
然而,在使用 Chrome 的 DevTools 时,我注意到十六进制和二进制数字文字在 in
关键字之前需要一个 space:
Internet Explorer 对所有三个测试都返回 true,而 FireFox 48.0.1 对第一个测试抛出一个 SyntaxError (1in foo
),但是字符串文字是可以的 ('1'in foo==true
)。
似乎解析 JavaScript 应该没有问题,允许关键字紧挨着数字文字,但我在 ECMAScript 规范中找不到任何明确的规则(其中任何一个)。
进一步测试表明,Chrome 和 FireFox(IE11 不支持 for..of 循环)都允许像 for(var i of[1,2,3])...
这样的语句,并且 typeof"string"
在所有三个中都有效.
哪种行为是正确的?事实上,它是在我错过的某个地方定义的,还是所有这些效果都是每个浏览器解析器的特性造成的?
不是专家 - 我没有做过 JS 编译器,但做过其他的。
ecma-262.pdf有点模糊,但是很明显,像1 in foo
这样的表达式应该被解析为3个输入元素,都是token。每个token是一个CommonToken
(11.5);在这种情况下,我们得到 numericLiteral
、identifierName
(是的,in
是一个 identifierName
)和 identifierName
。解析 0b1 in foo
时也是如此(见 11.8.3).
那么,当你取出 WS 时会发生什么?它没有明确涵盖(据我所知),但它是编写词法分析器扫描最长字符序列(可能与您可能正在寻找的内容匹配)时的常见做法(在其他语言中)。第 11 节的介绍几乎完全是这样说的:
The source text is scanned from left to right, repeatedly taking the longest possible sequence of code points as the next input element.
因此,对于 0b1in foo
,词法分析器经过 0b1
,它匹配一个数字文字,然后到达 i
,给出 0b1i
,它不匹配任何东西.因此它将最长的匹配项 (0b1
) 作为标记传递给解析器的其余部分,并在 i
处再次开始。它找到 n
,然后是 WS,因此将 in
作为第二个标记传递,依此类推。
所以,基本上,奇怪的是,IE 看起来是正确的。
TL;DR 如果在这些情况下不需要空格,代码的解释方式将不会发生变化,但它是规范的一部分。
查看 source code of v8 that handles number literal parsing, it cites ECMA 262 § 7.8.3:
The source character immediately following a NumericLiteral must not be an IdentifierStart or DecimalDigit.
NOTE For example:
3in
is an error and not the two input elements 3 and in.
这部分似乎与第7部分的介绍相矛盾。但是,打破该规则并允许解析3in
似乎不会有任何问题。在某些情况下,文字和标识符之间不允许有空格会改变源代码的解析方式,但所有情况只会改变生成的错误。