在[]导致Javascript错误之前没有分号?

exe*_*ook 10 javascript arrays syntax automatic-semicolon-insertion

var a = [1, 2, 3, 4];
var b = [10, 20, 30, 40];
console.log([a, b].length)[a, b].some(function(x) {
  x.push(x.shift())
});
Run Code Online (Sandbox Code Playgroud)

这段代码导致我今天非常惊讶

[a,b].some(function(x){ x.push(x.shift()) });
      ^
TypeError: Cannot call method 'some' of undefined
Run Code Online (Sandbox Code Playgroud)

显然JavaScript'自动分号插入'在这里没有按预期工作.但为什么?

我知道你可能会建议在;任何地方使用以避免这样的事情,但问题不在于它是否更好使用;.我想知道这里究竟发生了什么?

Dan*_*n M 14

当我担心分号插入时,我会想到在它们之间没有任何空格的情况下,所讨论的行会是什么样子.在你的情况下,那将是:

console.log([a,b].length)[a,b].some(function(x){ etc });
Run Code Online (Sandbox Code Playgroud)

在这里,您告诉Javascript引擎调用console.log长度[a,b],然后查看[a,b]该调用结果的索引.

console.log返回一个字符串,因此您的代码将尝试查找b该字符串的属性,该字符串未定义,并且调用undefined.some()失败.

这是有趣的是,str[a,b]将解决以str[b]假设str是一个字符串.正如Kamil指出的那样,a,b是一个有效的Javascript表达式,并且该表达式的结果很简单b.

  • `arr [a,b]`不是多维数组访问.它与`arr [b]`相同,因为`a,b`是有效的表达式,它具有最后一个逗号后面的内部表达式的值. (4认同)

Myr*_*tol 8

通常,可以说在新行上定义数组时隐式分号很容易失败,因为在新行上定义的数组被解释为对前一行表达式值的属性访问.

如果在新行导致解析错误之后没有结束语句,Javascript只会考虑使用新行来标记语句的结尾.请参阅JavaScript的自动分号插入(ASI)的规则是什么?EcmaScript 5规范的确切规则.(感谢Rob W和众人瞩目)

会发生什么是以下情况:

代码被解释为

console.log([a,b].length)[a,b].some(function(x){ x.push(x.shift()) });
Run Code Online (Sandbox Code Playgroud)

即所有作为一个声明.

现在解析声明:

some 被称为的价值 console.log([a,b].length)[a,b]

的值console.log([a,b].length)[a,b]是通过利用返回值来计算console.log([a,b].length)(undefined),然后试图用的值的名称来访问属性a,b. a,b计算值b(在控制台中尝试).没有值为of b的属性undefined,因此结果值undefined也是如此.

有没有一种方法someundefined,因此错误.


Bha*_*ikh 6

JavaScript不会将每个换行符视为分号.它通常只在没有分号的情况下解析代码时才将换行符视为分号.基本上,如果下一个非空格字符不能被解释为当前语句的延续,则JavaScript将换行符视为分号.JavaScript - 权威指南:第6版.第2.4节

所以,在你的情况下,它将线条解释为类似的东西

console.log([a,b].length)[a,b].some(function(x){ x.push(x.shift()) });
Run Code Online (Sandbox Code Playgroud)

这就是出错的原因.JavaScript正试图对结果执行数组访问console.log([a,b].length).根据JavaScript引擎和返回值console.log,您可能会遇到不同的错误.