在javascript中的高阶函数中使用原型函数 [英] Using prototype functions in higher order functions in javascript
问题描述
我正在尝试使用reduce合并数组数组,我发现可以使用Array.prototype.concat函数,如下所示:
I'm trying to concat an array of arrays using reduce and I figured that I could use the Array.prototype.concat function like this:
arr = [[1],[2],[3]]
arr.reduce((a, b) => Array.prototype.concat(a, b), [])
哪个工作正常,并给我数组 [1、2、3 ]
。然后我想我可以变得更聪明,像这样:
Which works fine and gives me the array [1, 2, 3]
. Then I thought I could be even smarter and do it like this:
arr = [[1],[2],[3]]
arr.reduce(Array.prototype.concat, [])
此但是给我一个错误:
TypeError: Array.prototype.concat called on null or undefined
at Array.reduce (native)
at Object.<anonymous> (/home/axel/Developer/temp/reduce2.js:2:5)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.runMain (module.js:590:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
似乎认为 Array.prototype.concat
是未定义
。为什么会这样?
It seems to think that Array.prototype.concat
is undefined
. Why is this?
推荐答案
concat
相对于某个对象(即方法执行的 this
值)。将函数传递给函数时,不会传递任何 this
值。因此,您实际上在做类似的事情:
concat
operates as a method with respect to some object (i.e., the this
value of the method's execution). When you pass a function into a function, you do not pass along any this
value. Thus, you're effectively doing something similar to:
var rawConcat = Array.prototype.concat;
rawConcat(a,b);
您可以使用 bind
创建副本具有特定的函数烧入它的函数:
You can use bind
to create a copy of a function with a particular this
burned into it:
arr.reduce(Array.prototype.concat.bind(Array.prototype), [])
但是,现在已经清除,还有其他一些问题使您无法执行此操作。
However, now that that's cleared up, there are several other issues that stop you from doing this.
其中一个,实际上是减少
获取四个参数,包括当前索引和整个数组。通过让您的(a,b)=>
lambda只将这四个参数中的两个传递给 concat
来忽略它们。很好,但是当您直接提供一个函数作为 reduce
的参数时,它将使用所有四个参数,因此您将得到调用<$ c $的结果c> Array.prototype.concat(a,b,currentIndex,arr)。
For one, reduce
actually gets four arguments, including the current index and the whole array. You ignore these by having your (a,b)=>
lambda only pass two of those four arguments into concat
. That's fine, but when you supply a function directly as an argument to reduce
, it will use all four arguments, so you'll get the result of the call Array.prototype.concat(a, b, currentIndex, arr)
.
此外,您正在做的不是明智地使用 Array.prototype
。 concat
函数连接其参数,并将其附加到 this
值的副本中。由于 Array.prototype
本身只是一个空数组(尽管具有许多其他数组用作继承属性的自有属性),所以这实际上与 []。concat(a,b)
或(也许更可读) a.concat(b)
。
Furthermore, what you're doing isn't a sensible use of Array.prototype
. The concat
function concatenates its arguments and appends them to a copy of the this
value. Since Array.prototype
is itself just an empty array (albeit with many own-properties that other arrays use as inherited properties), this is effectively the same as [].concat(a,b)
or (perhaps even more readably) a.concat(b)
.
这篇关于在javascript中的高阶函数中使用原型函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!