Pab*_*dez 25 javascript arrays foreach function
这只是出于好奇,但是你们中的任何人都知道为什么这段代码不起作用?
[1, 2, 3, 4, 5].forEach(console.log);
// Prints 'Uncaught TypeError: Illegal invocation' in Chrome
Run Code Online (Sandbox Code Playgroud)
另一方面,这似乎工作正常:
[1, 2, 3, 4, 5].forEach(function(n) { console.log(n) });
Run Code Online (Sandbox Code Playgroud)
那么......?
Ray*_*oal 25
值得指出的是,实施中的行为存在差异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 ]
Run Code Online (Sandbox Code Playgroud)
这是因为回调forEach是一个三参数函数,它取值,索引和数组本身.该函数console.log可以看到这三个参数并尽职地记录它们.
但是,在Chrome浏览器控制台下,您可以获得
> [1,2,3,4,5].forEach(console.log);
TypeError: Illegal invocation
Run Code Online (Sandbox Code Playgroud)
在这种情况下,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 ]
Run Code Online (Sandbox Code Playgroud)
但是有另一种方法:注意第二个参数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 ]
Run Code Online (Sandbox Code Playgroud)
适用于我的Chrome控制台和节点.当然,我确定你想要的只是价值观,所以我担心最好的解决方案是:
> [1,2,3,4,5].forEach(function (e) {console.log(e)});
1
2
3
4
5
Run Code Online (Sandbox Code Playgroud)
节点的行为是否是一个错误,或者它只是利用console.log了ECMA未指定的事实本身就很有趣.但是变化的行为,以及你必须知道你的回调是否使用的事实this很重要,这意味着我们必须回归到直接编码,即使它由于关键字而冗长function.
Tom*_*icz 11
这有效:
[1,2,3,4,5].forEach(console.log.bind(console));
Run Code Online (Sandbox Code Playgroud)
实际上正如@SLaks指出的那样,console.log似乎在this内部使用,当它作为参数传递时,this现在引用数组实例.
解决方法很简单:
var c = console.log.bind(console);
[1,2,3,4,5].forEach(c);