[英]No semicolon before [] is causing error in JavaScript
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()) });
I was extremely surprised today when this code caused今天当这段代码导致我非常惊讶
[a,b].some(function(x){ x.push(x.shift()) });
^
TypeError: Cannot call method 'some' of undefined
Obviously the JavaScript 'auto semicolon insertion' is not working as expected here.显然,JavaScript 的“自动分号插入”在这里没有按预期工作。 But why?
但为什么?
I know you might recommend to use ;
我知道你可能会推荐使用
;
everywhere to avoid something like that, but the question is not about whether it is better to use ;
到处都可以避免类似的事情,但问题不在于是否更好地使用
;
or not.或不。 I would love to know what exactly happens here?
我很想知道这里到底发生了什么?
When I'm worried about semicolon insertion, I think about what the lines in question would look like without any whitespace between them.当我担心分号插入时,我会考虑相关行之间没有任何空格的情况。 In your case, that would be:
在你的情况下,那将是:
console.log([a,b].length)[a,b].some(function(x){ etc });
Here you're telling the Javascript engine to call console.log
with the length of [a,b]
, then to look at index [a,b]
of the result of that call.在这里,您告诉 Javascript 引擎以
[a,b]
的长度调用console.log
,然后查看该调用结果的索引[a,b]
。
console.log
returns a string, so your code will attempt to find property b
of that string, which is undefined, and the call to undefined.some()
fails. console.log
返回一个字符串,因此您的代码将尝试查找该字符串的未定义属性b
,并且对undefined.some()
的调用失败。
It's interesting to note that str[a,b]
will resolve to str[b]
assuming str is a string.有趣的
str[a,b]
假设 str 是一个字符串, str[a,b]
将解析为str[b]
。 As Kamil points out, a,b
is a valid Javascript expression, and the result of that expression is simply b
.正如 Kamil 指出的那样,
a,b
是一个有效的 Javascript 表达式,该表达式的结果只是b
。
In general, one could say that implicit semi-colon's can easily fail when defining an array on a new line, because an array defined on a new line is interpreted as a property access of the value of the expression on the previous line.一般来说,可以说在新行上定义数组时隐式分号很容易失败,因为在新行上定义的数组被解释为对上一行表达式值的属性访问。
Javascript does only consider new lines to mark the end of a statement if not ending the statement after this new line would cause a parse error.如果在这个新行之后不结束语句会导致解析错误,Javascript 只会考虑新行来标记语句的结束。 See What are the rules for JavaScript's automatic semicolon insertion (ASI)?
请参阅JavaScript 的自动分号插入 (ASI) 的规则是什么? and EcmaScript 5 spec for the exact rules.
和EcmaScript 5 规范的确切规则。 (Thanks to Rob W and limelights)
(感谢 Rob W 和聚光灯下)
What happens is the following:发生的情况如下:
The code get interpreted as代码被解释为
console.log([a,b].length)[a,b].some(function(x){ x.push(x.shift()) });
ie all as one statement.即全部作为一个声明。
Now parse the statement:现在解析语句:
some
is called on the value of console.log([a,b].length)[a,b]
some
在console.log([a,b].length)[a,b]
的值上被调用
the value of console.log([a,b].length)[a,b]
is computed by taking the returned value of console.log([a,b].length)
( undefined
) and then trying to access the property with the name of the value of a,b
. console.log([a,b].length)[a,b]
是通过获取console.log([a,b].length)
( undefined
) 的返回值然后尝试访问该属性来计算的与a,b
的值的名称。 a,b
evaluates to the value of b
(try it in your console). a,b
的值就值b
(尝试在你的控制台)。 There's no property with the value of b
of undefined
, so the resulting value will be undefined
as well.没有
undefined
值为b
的属性,因此结果值也将是undefined
。
There's no method some
on undefined
, hence the error.在
undefined
上没有方法some
,因此出现错误。
JavaScript doesn't treat every line break as a semicolon. JavaScript 不会将每个换行符都视为分号。 It usually treats line breaks as semicolons only if it can't parse the code without the semicolons.
仅当它不能在没有分号的情况下解析代码时,它通常将换行符视为分号。 Basically, JavaScript treats a line break as a semicolon if the next non-space character cannot be interpreted as a continuation of the current statement.
基本上,如果下一个非空格字符不能被解释为当前语句的延续,JavaScript 会将换行符视为分号。 JavaScript - The Definitive Guide: 6th Ed.
JavaScript - 权威指南:第 6 版。 section 2.4
第 2.4 节
So, in your case, it is interpreting the line as something like因此,在您的情况下,它将该行解释为类似
console.log([a,b].length)[a,b].some(function(x){ x.push(x.shift()) });
And that is the reason for error.这就是错误的原因。 JavaScript is trying to perform array-access on the results of
console.log([a,b].length)
. JavaScript 正在尝试对
console.log([a,b].length)
的结果执行数组访问。 Depending on the JavaScript engine and the return value of console.log
, you might get different errors.根据 JavaScript 引擎和
console.log
的返回值,您可能会收到不同的错误。
If it is the last statement of the function or flow, you can avoid ';'
如果是函数或流程的最后一条语句,则可以避免
';'
but it is recommended to put ';'
但建议放
';'
at the end of the each statement to avoid such error.在每个语句的末尾以避免此类错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.