JavaScript新手在这里。今天我学会了reduce
并开始实现我自己的数组展平功能。
我拥有的是
var array = [[1, 2], [3, 4, 5], [6]];
var result = array.reduce(Array.prototype.concat, []); // Causes Uncaught TypeError: Array.prototype.concat called on null or undefined
var result = array.reduce(Array.prototype.concat.call, []); // Causes Uncaught TypeError: undefined is not a function
虽然Merge/flatten an array of arrays in JavaScript?中的答案是优雅和惯用的,但我真的很感激我的尝试失败的例证。
答案 0 :(得分:4)
您的代码等同于
result = array.reduce(fn, []);
function fn(a, b, index, array) { // this is the arguments reduce sends to the callback
return Array.prototype.concat.call(null, a, b, index, array);
}
你能发现问题吗?
答案 1 :(得分:2)
您对Array.prototype.concat.call
有正确的想法。使用Array.prototype.concat
,调用将如下所示:
var concat = Array.prototype.concat;
concat(concat(concat([],
[1, 2]),
[3, 4, 5]),
[6])
不起作用,因为Array.prototype.concat
将其参数连接到this
;将其称为concat()
会为this
提供undefined
。 call
怎么样?
var call = Array.prototype.concat.call;
call(call(call([],
[1, 2]),
[3, 4, 5]),
[6])
这会遇到同样的问题,但使用Function.prototype.call
(Array.prototype.concat
是一个与其他函数类似的函数,并从call
继承其Function.prototype
方法。 call
尝试调用this
,但将其称为call()
会为this
提供undefined
。
您可以传递Function.prototype.call.bind(Array.prototype.concat)
...如果reduce
没有使用更多参数调用其函数,而不仅仅是累加器和当前项。但它确实传递了当前项目和上下文数组的索引,并且通过仅传递包含一些内置函数的Array.prototype.concat
来破坏任何实现此工作的机会。
答案 2 :(得分:0)
这是因为Array.prototype.concat
需要一个函数原型,这样它就是一个数组或值列表,可以连接到主数组。
但是,回复Array.prototype.reduce
需要accumulator
,currentValue
,currentIndex
和array
作为参数。
参数(以及他们应该做的事情)不匹配,因此会出现意外结果或错误。