编程语言
首页 > 编程语言> > Javascript-为什么我不能在Chrome(和Safari)中将console.log作为回调参数传递?

Javascript-为什么我不能在Chrome(和Safari)中将console.log作为回调参数传递?

作者:互联网

以下代码段在Firefox中运行时会在Chrome(和Safari)中产生错误.

我希望在javascript控制台中显示2个数字,但是在Chrome浏览器中,我只会第一个出现,然后是Uncaught TypeError:非法调用

// a generic promise that return a random float
var makePromise = function() {
  return $.Deferred().resolve(Math.random());
}

// This works in all browsers
makePromise().then(function(d) {
  console.log(d);
});
// This works in firefox only
makePromise().then(console.log);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

为什么会这样呢?

旁注:我的问题和this question不同.

更新

多亏了注释和答案,可以将console.log用作回调,这需要做

makePromise().then(console.log.bind(console));

解决方法:

在chromebook中,我可以按如下方式复制问题:

function do4(cb){ cb(1); cb(2); cb(3); cb(4); }

do4(console.log)
VM1491:2 Uncaught TypeError: Illegal invocation
    at do4 (<anonymous>:2:19)
    at <anonymous>:2:12
    at Object.InjectedScript._evaluateOn (<anonymous>:905:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:838:34)
    at Object.InjectedScript.evaluate (<anonymous>:694:21)do4 @ VM1491:2(anonymous function) @ VM1552:2InjectedScript._evaluateOn @ VM1288:905InjectedScript._evaluateAndWrap @ VM1288:838InjectedScript.evaluate @ VM1288:694

但这工作正常,并且确实指出了问题所在:

do4(console.log.bind(console))
VM1491:2 1
VM1491:2 2
VM1491:2 3
VM1491:2 4

这是为什么?

在chrome中,控制台本身会返回原型控制台的对象,
 看:

console
Console {} memory: MemoryInfo__proto__: Console

将控制台作为对象似乎有些奇怪,但事实并非如此. console还有其他一些较少使用的方法,这些方法的使用率不如console.log,但记录在MDN Console DocsChrome Console Docs

在这里,我们讨论了一个大的Javascript主义,它会使人们感到困惑:

JavaScript方法是未绑定的方法.也就是说,这些方法未绑定到任何特定对象.

因此,console.log是一个函数,但是它仅是函数,并且不会保留其与控制台的绑定.

变量绑定在函数的代码中通过魔术此变量进行引用,该变量可以用function.bindfunction.apply设置.

调用console.log()时,JS会将功能代码的this绑定到控制台对象.但是,当console.log仅作为函数传递时,它不会进行绑定,因此其他代码可以更灵活地使用它.对于console.log和许多其他方法,此行为很不方便,但在某些情况下会增加所需的灵活性.

标签:javascript,function,firefox,google-chrome,jquery-deferred
来源: https://codeday.me/bug/20191010/1887370.html