Javascript 为什么';t console.log作为参数传递给forEach时是否工作?
这只是出于好奇,但你们有人知道为什么这段代码不起作用吗Javascript 为什么';t console.log作为参数传递给forEach时是否工作?,javascript,arrays,function,foreach,Javascript,Arrays,Function,Foreach,这只是出于好奇,但你们有人知道为什么这段代码不起作用吗 [1, 2, 3, 4, 5].forEach(console.log); // Prints 'Uncaught TypeError: Illegal invocation' in Chrome 另一方面,这似乎很有效: [1, 2, 3, 4, 5].forEach(function(n) { console.log(n) }); 那么 我不能说我见过这种语法,但我猜是因为log需要一个参数,即message/object/etc
[1, 2, 3, 4, 5].forEach(console.log);
// Prints 'Uncaught TypeError: Illegal invocation' in Chrome
另一方面,这似乎很有效:
[1, 2, 3, 4, 5].forEach(function(n) { console.log(n) });
那么 我不能说我见过这种语法,但我猜是因为log需要一个参数,即message/object/etc来登录控制台 在第一个示例中,您只是将一个函数引用传递给forEach,如果您的函数不需要paramater,而paramater会使函数按预期的方式运行,那么这是很好的。在第二个示例中,您传入e,然后将其记录下来。这样做:
[1,2,3,4,5].forEach(console.log.bind(console));
实际上正如@SLaks指出的,console.log似乎在内部使用
this
,当它作为参数传递时,this现在引用数组实例
解决方法很简单:
var c=console.log.bind(console)代码>
[1,2,3,4,5].forEach(c)代码>值得指出的是,console.log
的实现在行为上存在差异。在节点v0.10.19下,不会出现错误;你可以简单地看到:
> [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 ]
这是因为对forEach
的回调是一个三参数函数,包含值、索引和数组本身。函数console.log
查看这三个参数并尽职尽责地记录它们
然而,在Chrome浏览器控制台下,您可以
> [1,2,3,4,5].forEach(console.log);
TypeError: Illegal invocation
在这种情况下,bind
将起作用:
但是还有另一种方法:请注意,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 ]
它在Chrome控制台和节点中为我工作。当然,我相信你想要的只是价值观,所以我担心最好的解决方案确实是:
> [1,2,3,4,5].forEach(function (e) {console.log(e)});
1
2
3
4
5
无论节点的行为是一个bug,还是仅仅利用了ECMA未指定的console.log
这一事实本身都很有趣。但是不同的行为,以及您必须知道回调是否使用this
这一事实非常重要,这意味着我们必须退回到直接编码,即使由于关键字函数
确实很冗长。我会自己回答的,我真是个白痴能把它删掉吗?这真的没什么帮助=/@PabloFernandez我是说这个问题,但我想有人很喜欢这个问题,所以也许它毕竟对某些人有用。。。我从来都不清楚投票是来自于那些发现问题真正有用的人,还是来自于试图玩弄系统的回答者。@GGG我很好,但你认为这真的有必要吗?它得到了2张赞成票。。。也许我们可以把它作为一个在js中谈论bind
的问题的副本来结束?也许最好是把它作为一个关于如何解决这个
的问题的副本来结束。。。除了bind
之外,还有其他方法可以解决这个问题forEach
正在传递一个参数。我试图指出的一点是,该参数需要传递到console.log,即console.log(e)Yes,而这正是发生的情况。函数表达式中的函数和属性中的函数没有区别。答案很好,我想将其标记为已接受,但您能解释一下(对于那些不知道的人)您的代码的功能吗?如果不是的话,恐怕我得接受我的,因为我的资料要多一些。Thanks在节点v6中不起作用:>[1,2,3]。forEach(console.log.bind(console))10[1,2,3]2[1,2,3]3[1,2,3]在节点v7中仍然失败。如果您只想记录数组的元素,我将避免使用此解决方案。这个答案将console.log
应用于回调的三个参数,并打印出非常混乱和不需要的输出。IMHO说,当答案被写出来时,它可能确实起作用了,但这只是因为特定的JavaScript实现是错误的。回调现在有三个参数。感谢您的解释-读者可能会找到以下链接,其中描述了Array.prototype.forEach()的预期参数,以及传递给所提供回调的参数(如您所讨论的):尽管使用箭头函数,您可以使用:[1,2,3].forEach(v=>console.log(v))
;-)事实上,我不敢相信我在2014年初仍然使用长形式函数表达式作为forEach
(和friends)的参数。不过很快就换了。
> [1,2,3,4,5].forEach(function (e) {console.log(e)});
1
2
3
4
5