[英]Why doesn't console.log work when passed as a parameter to forEach?
This is just out of curiosity, but do any of you have an idea why this code won't work? 这只是出于好奇,但是你们中的任何人都知道为什么该代码无法正常工作吗?
[1, 2, 3, 4, 5].forEach(console.log);
// Prints 'Uncaught TypeError: Illegal invocation' in Chrome
On the other hand, this seems to work fine: 另一方面,这似乎很好用:
[1, 2, 3, 4, 5].forEach(function(n) { console.log(n) });
So... ? 那...
It's worth pointing out that there is a difference in behavior in the implementation of console.log
. 值得指出的是,
console.log
的实现在行为上有所不同。 Under node v0.10.19 you do not get an error; 在节点v0.10.19下,您不会收到错误; you simply see this:
您只是看到以下内容:
> [1,2,3,4,5].forEach(console.log);
1 0 [ 1, 2, 3, 4, 5 ]
2 1 [ 1, 2, 3, 4, 5 ]
3 2 [ 1, 2, 3, 4, 5 ]
4 3 [ 1, 2, 3, 4, 5 ]
5 4 [ 1, 2, 3, 4, 5 ]
This is because the callback to forEach
is a three-parameter function taking the value, the index, and the array itself. 这是因为对
forEach
的回调是一个三参数函数,接受值,索引和数组本身。 The function console.log
sees those three parameters and dutifully logs them. 函数
console.log
看到这三个参数,并认真记录它们。
Under the Chrome browser console, however, you get 但是,在Chrome浏览器控制台下,
> [1,2,3,4,5].forEach(console.log);
TypeError: Illegal invocation
and in this case, bind
will work: 在这种情况下,
bind
将起作用:
> [1,2,3,4,5].forEach(console.log.bind(console));
1 0 [ 1, 2, 3, 4, 5 ]
2 1 [ 1, 2, 3, 4, 5 ]
3 2 [ 1, 2, 3, 4, 5 ]
4 3 [ 1, 2, 3, 4, 5 ]
5 4 [ 1, 2, 3, 4, 5 ]
but there is an alternative way: note that the second parameter to forEach
takes the value of this
to use in the callback: 但有另一种方法:注意, 到第二个参数
forEach
需要的值this
在回调的使用方法:
> [1,2,3,4,5].forEach(console.log, console)
1 0 [ 1, 2, 3, 4, 5 ]
2 1 [ 1, 2, 3, 4, 5 ]
3 2 [ 1, 2, 3, 4, 5 ]
4 3 [ 1, 2, 3, 4, 5 ]
5 4 [ 1, 2, 3, 4, 5 ]
which works in the Chrome console and node for me. 在我的Chrome控制台和节点中均可使用。 Of course, I'm sure what you want is just the values, so I'm afraid the best solution is, indeed:
当然,我确定您想要的只是值,因此,恐怕最好的解决方案确实是:
> [1,2,3,4,5].forEach(function (e) {console.log(e)});
1
2
3
4
5
Whether node's behavior is a bug, or it simply takes advantage of the fact that console.log
is not specified by ECMA is interesting in its own right. 节点的行为是错误还是仅利用ECMA未指定
console.log
的事实本身就很有趣。 But the varying behavior, and the fact that you have to be aware of whether your callback uses this
is important and means we have to fall back to direct coding, even if it is verbose thanks to the keyword function
. 但是变化的行为以及必须知道回调是否使用了回调函数
this
很重要,这意味着我们必须退回到直接编码,即使由于关键字function
而变得冗长。
这有效:
[1,2,3,4,5].forEach(console.log.bind(console));
Actually as @SLaks pointed out, console.log seems to be using this
internally and when it's passed as a parameter this
now refers to the array instance. 其实作为@SLaks指出,执行console.log好像是用
this
内部,当它作为一个参数传递真实this
现指阵列实例。
The workaround for that is simply: 解决方法很简单:
var c = console.log.bind(console);
[1,2,3,4,5].forEach(c);
I can't say I've seen that syntax, but my guess is because log expects a parameter, being the message/object/etc to log in the console. 我不能说我已经看过这种语法,但是我的猜测是因为log需要一个参数,即要登录控制台的message / object / etc。
in the first example, you are just passing a function reference to forEach, which is fine if your function doesn't expect paramater which make the function behave as expected. 在第一个示例中,您只是将一个函数引用传递给forEach,如果您的函数不希望参数使函数按预期运行,这很好。 In the second example you pass in e and then log it.
在第二个示例中,您传入e,然后将其记录下来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.