为什么我不能在 Chrome(和 Safari)中将 console.log 作为回调参数传递?
Why I can't pass console.log as a callback argument in Chrome (and Safari)?
以下代码片段在 Firefox 中运行时会在 Chrome(和 Safari)中产生错误。
我希望在 javascript 控制台中显示 2 个数字,但在 Chrome 中我只得到第一个,然后是 Uncaught TypeError: Illegal invocation
// 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>
为什么会这样?
旁注:我的问题与 不同。
更新
感谢评论和回答使用 console.log
作为回调需要做
makePromise().then(console.log.bind(console));
在 chrome一本书中,我可以将问题复制如下:
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
本身 returns 原型 Console
的 Object
,
看:
console
Console {} memory: MemoryInfo__proto__: Console
将 console
视为 Object
似乎很奇怪,但确实如此。 console
还有其他几种较少使用的方法,不像 console.log
那样经常使用,但在 MDN Console Docs and Chrome Console Docs
中有记录
这里我们进入了一个大的 Javascript-可能会混淆人们的主义:
Javascript 方法是 未绑定方法 。也就是说,这些方法不绑定到任何特定对象。
所以 console.log
是一个函数,但它只是函数,并没有保留 this
到 console
的绑定。
变量绑定在函数代码中由一个神奇的 this
变量引用,可以用 function.bind
or function.apply
设置。
调用console.log()
时,JS将函数代码的this
绑定到console
对象上。但是当console.log
只是作为一个函数传递时,它并没有做绑定,这样其他代码可以更灵活地使用它。这种行为对于 console.log 和许多其他方法来说是不方便的,但在某些情况下增加了所需的灵活性。
// a generic promise that return a random float
var makePromise = function() {
// set `this` to `window.console` ,
// pass arguments within array
return $.Deferred().resolveWith(window.console, [Math.random()]);
}
// This works in all browsers
makePromise().then(console.log)
//.then(function(d) {
// console.log(d);
//});
// This works in firefox only
makePromise().then(console.log);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
以下代码片段在 Firefox 中运行时会在 Chrome(和 Safari)中产生错误。
我希望在 javascript 控制台中显示 2 个数字,但在 Chrome 中我只得到第一个,然后是 Uncaught TypeError: Illegal invocation
// 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>
为什么会这样?
旁注:我的问题与
更新
感谢评论和回答使用 console.log
作为回调需要做
makePromise().then(console.log.bind(console));
在 chrome一本书中,我可以将问题复制如下:
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
本身 returns 原型 Console
的 Object
,
看:
console
Console {} memory: MemoryInfo__proto__: Console
将 console
视为 Object
似乎很奇怪,但确实如此。 console
还有其他几种较少使用的方法,不像 console.log
那样经常使用,但在 MDN Console Docs and Chrome Console Docs
这里我们进入了一个大的 Javascript-可能会混淆人们的主义:
Javascript 方法是 未绑定方法 。也就是说,这些方法不绑定到任何特定对象。
所以 console.log
是一个函数,但它只是函数,并没有保留 this
到 console
的绑定。
变量绑定在函数代码中由一个神奇的 this
变量引用,可以用 function.bind
or function.apply
设置。
调用console.log()
时,JS将函数代码的this
绑定到console
对象上。但是当console.log
只是作为一个函数传递时,它并没有做绑定,这样其他代码可以更灵活地使用它。这种行为对于 console.log 和许多其他方法来说是不方便的,但在某些情况下增加了所需的灵活性。
// a generic promise that return a random float
var makePromise = function() {
// set `this` to `window.console` ,
// pass arguments within array
return $.Deferred().resolveWith(window.console, [Math.random()]);
}
// This works in all browsers
makePromise().then(console.log)
//.then(function(d) {
// console.log(d);
//});
// This works in firefox only
makePromise().then(console.log);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>