这只是出于好奇,但是你们有没有人知道为什么这段代码不起作用?
[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) });
所以... ?
这只是出于好奇,但是你们有没有人知道为什么这段代码不起作用?
[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) });
所以... ?
值得指出的是,在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
将起作用:
> [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 ]
但还有一种替代方法:请注意,第二个参数 toforEach
取值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 控制台和节点。当然,我确定您想要的只是value观,所以恐怕最好的解决方案确实是:
> [1,2,3,4,5].forEach(function (e) {console.log(e)});
1
2
3
4
5
节点的行为是否是一个错误,或者它只是利用console.log
了 ECMA 未指定的事实本身就很有趣。但是不同的行为,以及你必须知道你的回调是否使用这一事实this
很重要,这意味着我们必须退回到直接编码,即使由于关键字 ,它变得冗长function
。
这有效:
[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);
我不能说我见过这种语法,但我的猜测是因为 log 需要一个参数,即消息/对象/等以登录控制台。
在第一个示例中,您只是将函数引用传递给 forEach,如果您的函数不期望使函数按预期运行的参数,这很好。在第二个例子中,你传入 e 然后记录它。