"is not a function" 代码中有另一个不相关的函数时出错

"is not a function" error when another unrelated function is in the code

我有两段代码,每段都按预期工作:

function Test() {}

let tmp = function() {
    console.log(this)
}
tmp.call(Test)

function Test() {}

(function() {
    console.log(this)
}).call(Test)

它们都产生了预期的输出:[Function: Test]

但是,当这些独立的代码片段组合在一起时,就会产生错误。所以,运行下面的代码

function Test() {}

let tmp = function() {
    console.log(this)
}
tmp.call(Test)

(function() {
    console.log(this)
}).call(Test)

结果

TypeError: tmp.call(...) is not a function

我找到了一个不太优雅的修复方法,它为第二个代码片段添加了延迟。因此,以下将产生所需的输出([Function: Test] 两次):

function Test() {}

let tmp = function() {
    console.log(this)
}
tmp.call(Test)

setTimeout(() => {
    (function() {
        console.log(this)
    }).call(Test)
}, 100);

超时似乎可以解决这个问题的事实让我认为它与某些异步内容有关,但我无法确切解释为什么会发生。

您正在成为自动分号插入陷阱的受害者。代码

tmp.call(Test)

(function() {
    console.log(this)
}).call(Test)

被解释为好像写成

tmp.call(Test)(function() { console.log(this) }).call(Test)

如果引入分号:

tmp.call(Test);

(function() {
    console.log(this)
}).call(Test)

那就可以了。

确切的规则涉及一些 "legalese" 有点难以理解,但基本思想(在本例中)是当考虑换行符时表达式在语法上可以工作时不会插入分号成为一个简单的 space 角色。

你的代码片段是这样解释的:

function Test() {}

let tmp = function() {
    console.log(this)
}
tmp.call(Test)(function() {
    console.log(this)
}).call(Test)

要修复它,请在 tmp.call(Test)

后添加一个分号