JavaScript中的未捕获类型错误:非法调用

41

我正在创建一个lambda函数,用具体的参数执行第二个函数。这段代码在Firefox中可以工作,但在Chrome中无法工作,它的检查器显示了一个奇怪的错误:Uncaught TypeError: Illegal invocation。我的代码有什么问题?

var make = function(callback,params){
    callback(params);
}

make(console.log,'it will be accepted!');

1
如果我使用console.log.bind(console)替换console.log,它可以在Chrome 12中工作。 - Dan D.
2
@DanD - 这表示log希望作为console的一个方法被调用,即它的this关键字必须引用console对象。 - RobG
你的 make 函数等同于 callback.call(null,params) - Jan Turoň
我想指出,在旧版本的IE中,console.log可能是一个可调用的宿主对象(没有call、apply或bind方法),而不是一个函数。 - hugomg
https://dev59.com/CGkv5IYBdhLWcg3w1kIJ#71283695 - Rana Nadeem
2个回答

70

控制台的日志函数期望 this 指向控制台(内部)。考虑下面这段代码,它模拟了你遇到的问题:

var x = {};
x.func = function(){
    if(this !== x){
        throw new TypeError('Illegal invocation');
    }
    console.log('Hi!');
};
// Works!
x.func();

var y = x.func;

// Throws error
y();

以下是一个(有些愚蠢的)示例,但它可以工作,因为它在你的make函数中将this绑定到console

var make = function(callback,params){
    callback.call(console, params);
}

make(console.log,'it will be accepted!');
这也能行。
var make = function(callback,params){
    callback(params);
}

make(console.log.bind(console),'it will be accepted!');

4
您可以将需要'this'的函数包装成一个新的lambda函数,然后将其用作回调函数。
function make(callback, params) {
  callback(params);
}

make(function(str){ console.log(str); }, 'it will be accepted!');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接