【问题标题】:No semicolon before [] is causing error in JavaScript[] 之前没有分号导致 JavaScript 出错
【发布时间】:2013-05-15 21:56:50
【问题描述】:

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())
});

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

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

很明显,JavaScript 的“自动分号插入”在这里没有按预期工作。但为什么呢?

我知道您可能会建议在任何地方使用; 来避免类似的情况,但问题不在于使用; 是否更好。我很想知道这里到底发生了什么?

【问题讨论】:

标签: javascript arrays syntax automatic-semicolon-insertion


【解决方案1】:

当我担心分号插入时,我会考虑有问题的行之间没有任何空格会是什么样子。在你的情况下,那将是:

console.log([a,b].length)[a,b].some(function(x){ etc });

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

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

有趣的是,假设 str 是一个字符串,str[a,b] 将解析为 str[b]。正如 Kamil 指出的那样,a,b 是一个有效的 Javascript 表达式,该表达式的结果就是 b

【讨论】:

  • arr[a, b] 不是多维数组访问。它与arr[b] 相同,因为a, b 是在最后一个逗号之后具有内部表达式值的有效表达式。
  • 我不认为 console.log 返回一个字符串。
【解决方案2】:

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

如果 not 在新行之后结束语句会导致解析错误,Javascript 只会考虑新行来标记语句的结尾。有关确切规则,请参阅 What are the rules for JavaScript's automatic semicolon insertion (ASI)?EcmaScript 5 spec。 (感谢 Rob W 和聚光灯)

会发生以下情况:

代码被解释为

console.log([a,b].length)[a,b].some(function(x){ x.push(x.shift()) });

即全部作为一个声明。

现在解析语句:

someconsole.log([a,b].length)[a,b] 的值调用

console.log([a,b].length)[a,b] 的值是通过获取console.log([a,b].length) (undefined) 的返回值,然后尝试访问具有a,b 值名称的属性来计算的。 a,b 评估为 b 的值(在您的控制台中尝试)。没有属性值为undefinedb,因此结果值也将是undefined

undefined 上没有方法 some,因此出现错误。

【讨论】:

    【解决方案3】:

    JavaScript 不会将每个换行符都视为分号。它通常对待线 仅当它无法解析没有分号的代码时才作为分号中断。基本上,如果下一个非空格字符不能解释为当前语句的延续,JavaScript 会将换行符视为分号。 JavaScript - The Definitive Guide: 6th Ed. section 2.4

    因此,在您的情况下,它将该行解释为

    console.log([a,b].length)[a,b].some(function(x){ x.push(x.shift()) });
    

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

    【讨论】:

      【解决方案4】:

      如果是函数或流程的最后一条语句,可以避免';',但建议在每条语句的末尾加上';',以避免出现此类错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-24
        • 2021-09-22
        • 2016-12-06
        • 1970-01-01
        • 2014-07-26
        • 2014-03-05
        相关资源
        最近更新 更多