为什么我无法在Chrome(和Safari)中将console.log作为回调参数传递? [英] Why I can't pass console.log as a callback argument in Chrome (and Safari)?

查看:213
本文介绍了为什么我无法在Chrome(和Safari)中将console.log作为回调参数传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我希望在javascript控制台中显示2个数字,在Chrome浏览器(和Safari)中,但在Chrome中,我只得到第一个,然后是 Uncaught TypeError:非法调用



  //返回一个随机floatvar的一个通用的承诺makePromise = function(){return $ .Deferred()。resolve(Math.random());} // This ();(console.log(d);}); //这在firefox onlymakePromise()。然后(console.log);  

< script src =https://ajax.googleapis.com/ajax/libs/jquery

$ b

为什么会发生这种情况?

注意:我的问题与这个问题不一样
$ b

更新



感谢评论和回答,使用 console.log 作为回调需要做的事情
$ b $ $ $ p $ makePromise()。然后(console.log.bind(console) );


解决方案

在chromebook中,我可以像下面这样复制问题:

 函数do4(cb){cb(1); CB(2); CB(3); CB(4); 
do4(console.log)
VM1491:2 Uncaught TypeError:非法调用
在do4(< anonymous>:2:19)
at<在Object.InjectedScript._evaluateOn(< anonymous>:905:140)上的
:Object.InjectedScript._evaluateAndWrap(< anonymous>:838:34)

(匿名函数)@ VM1552:2InjectedScript._evaluateOn @ VM1288:905InjectedScript._evaluateAndWrap @ VM1288:838InjectedScript.evaluate @ VM1288:694 $ b $在Object.InjectedScript.evaluate(<匿名> 694:21)do4 @ VM1491: b

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

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

为什么会这样?

在chrome中, console本身返回一个 Object 的原型 Console 看:

$ $ $ $ code $ console b $ b Console {}备忘录ry:MemoryInfo__proto__:Console



console 作为 Object ,但它是。 console 还有其他一些较少使用的方法,这些方法的使用频率不如 console.log ,但记录在 MDN控制台文档 Chrome控制台文档



在这里我们得到一个很大的Javascript-ism这可能会混淆人们:

Javascript方法是未绑定的方法。也就是说,这些方法并没有绑定到任何特定的对象上。
$ b $ <$> console.log 是一个函数,但是它只是函数,并不保留这个控制台的绑定。

变量绑定在函数的代码中被一个这个变量引用,它可以用< a href =https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind =nofollow> function.bind function.apply
$ b 当调用 console.log()时,JS执行函数代码的 控制台对象。但是当 console.log 只是作为一个函数传递时,它不会执行绑定,所以其他代码可以更灵活地使用它。这种行为是不方便console.log和许多其他方法,但在某些情况下增加了所需的灵活性。


The following snippet will produce an error in Chrome (and Safari) while it works in Firefox.

I'd expect to have 2 numbers shown in javascript console, but in Chrome I only get the first and then an 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>

Why is this happening?

Side note: my question is not the same as this question.

Update

Thanks to comments and answer to use console.log as callback one need to do

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

解决方案

In a chromebook I can duplicate the problem as follows:

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

But this works fine, and indeed points toward the problem:

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

Why is that?

In chrome, console by itself returns an Object of prototype Console, look:

console
Console {} memory: MemoryInfo__proto__: Console

It may seem odd thinking of console as an Object, but it is. console has several other lesser-used methods that are not used as often as console.log but are documented in MDN Console Docs and Chrome Console Docs

And here we get to a big Javascript-ism that can confuse people:

Javascript methods are unbound methods. That is, the methods are not bound to any particular object.

So console.log is a function, but it is the function only and does not preserve its binding of this to console.

The variable binding is referred to inside a function's code by a magic this variable, which can be set with function.bind or function.apply.

When console.log() is called, JS does the binding of the function code's this to the console object. But when console.log is merely passed as a function, it does not do the binding, so that other code can use it more flexibly. This behavior is inconvenient with console.log and many other methods, but in some cases adds needed flexibility.

这篇关于为什么我无法在Chrome(和Safari)中将console.log作为回调参数传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆