【问题标题】:How do I pass console.log as an argument to my JavaScript function?如何将 console.log 作为参数传递给我的 JavaScript 函数?
【发布时间】:2012-01-29 10:02:23
【问题描述】:

在下面的代码中,我可以使用 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);

【问题讨论】:

  • 如果你只传递 console 并在 forEach 函数中调用 log ,它将起作用。

标签: javascript


【解决方案1】:

一般情况下,您不能将方法直接传递给 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(或您选择的库中的类似函数,因为bind 在IE

//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 中的实际函数,(它是一个邪恶的宿主对象)你不能使用绑定、应用和调用方法在那个浏览器上,所以唯一的解决方法是回退到将调用包装在一个匿名函数中

doSomething( function(x){
    return console.log(x);
});

由于在匿名函数中包装 console.log 很长而且输入起来很烦人,我通常在开发和调试时添加以下全局函数:

function log(message){ return function(x){
    return console.log(message, x);
};};

forEach(['asd', 'zxc'], log('->'));

【讨论】:

    【解决方案2】:

    从这里: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

    【讨论】:

    • 那你为什么不能log = console.log呢?
    • @meze:因为console.log 将在内部引用this 并期望它是console。如果您“分离”log 方法,例如与var log = console.log 一样,此关联丢失并且this 将不再指向console(在这种情况下指向window - 如果您在浏览器中)。这就是.bind(obj) 的目的:它返回一个内部this 固定为obj 的方法。
    • 请记住,bind 并非在所有浏览器中都可用。请参阅@frm 的答案以获得不需要bind 的解决方案。
    • 这在 IE 上不起作用(至少是旧的)-console.log 不是函数,因此它缺少 bbind 调用和应用
    【解决方案3】:

    您可以使用匿名函数作为forEach()console.log() 之间的桥梁来解决问题

    forEach(["blah", "bac"], function (element) {
        console.log(element);
    });
    

    您的forEach() 仍然与处理程序无关,并且您不必使用bind() 来传递对console.log() 的工作引用。

    【讨论】:

      猜你喜欢
      • 2015-06-09
      • 2020-03-22
      • 1970-01-01
      • 2013-01-27
      • 2012-06-09
      • 1970-01-01
      • 2021-04-15
      • 2018-03-15
      • 1970-01-01
      相关资源
      最近更新 更多