"{.}不是函数,尽管从未作为函数调用

2022-03-12 00:00:00 typeerror javascript

如果紧接在匿名函数调用之前创建JSON对象,则在Firefox中得到TypeError: ({x:0, y:0}) is not a function,在Chrome中得到Uncaught TypeError: {(intermediate value)(intermediate value)} is not a function

但是,我从未将a作为函数调用。此外,当我将分号放在对象定义之后时,不会出现此错误。

根据http://inimino.org/~inimino/blog/javascript_semicolons,我不明白为什么在理论上需要分号。然而,由于某些原因,它仍然是必需的。为什么?

let a = { x: 0, y: 0 }

(() => {
    console.log('test')
})()


解决方案

正如其他人所说,这两个语句被理解为单一的、无意义的语句。我在这里感到恼火的是,没有人正确回答为什么这里会发生这种情况,而不是在其他情况下。

您在此处引用NPM风格指南:https://docs.npmjs.com/misc/coding-style.html 上面写着

在前导(或[行首。这可防止将表达式分别解释为函数调用或属性访问。

您的问题是因为第二条语句以([开头,这会混淆解析器。在这些情况下,需要使用分号。为什么分析器会被([混淆?因为例如{ x: 0, y: 0}["x"]将是有效代码。对于{ x: 0, y: 0}()也是如此,它是完全有效的,它只会崩溃。但是解析器无法知道它是否有意义,它必须在所有地方应用相同的规则。

请注意,NPM样式指南随后建议在这种情况下使用(将分号放在行中。因此,您可以这样写:

let a = { x: 0, y: 0 }

;(() => { // semi-colon at start of this line
    console.log('test')
})()

这样做的原因是,如果您将其放在第一个语句之后,然后编辑您的代码,则会重新引入该问题。例如,结果如下:

let a = { x: 0, y: 0 };

let b = { x: 1, y: 1 }

(() => { // this will fail
    console.log('test')
})()

相关文章