在下面的代码中,我可以使用print代替console.log,程序可以正常运行。但是我希望使用console.log但是我得到了
非法调用
在运行时
function forEach(array, action) {
for (var i=0; i<array.length; i++)
action(array[i]);
}
forEach(["blah", "bac"], console.log);
答案 0 :(得分:7)
一般情况下,您无法直接将方法传递给Javascript中的回调。 this
在函数调用点被绑定,具体取决于您调用它的形式,并且没有方法的自动绑定(例如,在Python中)
//does not work.
var obj = {
x: 17,
f: function(){ return this.x; }
};
//inside doSomething, f forgets its "this" should be obj
doSomething( obj.f )
在这些情况下,可以使用Function.prototype.bind
(或您选择的库中的类似函数,因为IE中不存在bind
&lt; = 8)
//works (for normal methods - see next bit for console.log in particular)
var obj = {
x: 17,
f: function(){ return this.x; }
};
doSomething( obj.f.bind(obj) )
不幸的是,这对于console.log来说并不总是这样。因为它不是IE中的实际函数,(它是一个邪恶的宿主对象)你不能使用bind,apply和call方法在浏览器上,所以唯一的解决方法是回退到在匿名函数中包装调用
doSomething( function(x){
return console.log(x);
});
由于在匿名函数中包装console.log很长并且对于类型I很烦,所以在我开发和调试时通常会添加以下全局函数:
function log(message){ return function(x){
return console.log(message, x);
};};
forEach(['asd', 'zxc'], log('->'));
答案 1 :(得分:4)
从这里开始:Create shortcut to console.log() in Chrome
您可以将console.log
替换为console.log.bind(console)
感谢@ julian-d:
因为
console.log
会在内部引用this
并期望它 是console
。如果您'分离'log
方法,例如像var log = console.log
一样,这种关联会丢失,这将不再指向console
(在这种情况下改为window
- 如果您在浏览器中)。 这是.bind(obj)
的目的:它返回一个方法 内部this
保持固定为obj
。
答案 2 :(得分:3)
您可以使用匿名函数解决问题,该函数充当forEach()
和console.log()
之间的桥梁
forEach(["blah", "bac"], function (element) {
console.log(element);
});
您的forEach()
仍然不知道该处理程序,您不必与bind()
玩耍,以便将工作引用传递给console.log()
。