concat + apply到底是做什么来使数组变平?

时间:2019-01-24 16:58:40

标签: javascript

我基本上已经记住了这个[].concat.apply([], a)来使未深层嵌套的数组变平,但是我不完全理解它是如何工作的。例如,apply从何而来?

它比arr.reduce((x,y) => [...x,...y])更有效率吗?

2 个答案:

答案 0 :(得分:4)

这有两个方面:

concat将传入的数组展平(到一个级别),仅包括结果数组中的元素:

console.log([1, 2, 3].concat(4, 5, [6, 7, 8]));

注意最后的数组是如何变平的。

applyFunction.prototype.apply:您可以使用它来调用一个函数,该函数指定应为this,并将该函数的参数作为数组提供。最后一点很关键:将数组的元素作为离散参数传递给concat,如果那些中的任何一个是数组,则concat将提取其内容。所以

let a = [[1, 2, 3], 4, 5, [6, 7, 8]];
a = [].concat.apply([], a);
//  ^^--- (1)       ^^--- (2)

...调用concat,其中this在上面的数组(2)中,并传入参数[1, 2, 3]45和{{ 1}}。 (数组(1)仅用于获取[6, 7, 8],然后扔掉。)

concat有点浪费(它创建两个扔掉的数组,两个都在上面指出),尽管这不太可能。确实应该是`Array.prototype.concat.apply([],尽管它仍然会创建并丢弃其中一个。(显然,您会将其塞入可重用的函数中,因此不必键入它每次。)

但是在现代JavaScript中,您可能需要改用flat,并在必要时使用polyfill:

[].concat.apply([], a)

以上内容适用于最新版本的Chrome,Firefox和Safari,但是您仍然可以使用polyfill在其他浏览器上使用它。

请注意,console.log( [ [1, 2, 3], 4, 5, [6, 7, 8] ].flat() );可以进行递归展平。默认情况下,它仅执行一个级别(如flat),但是如果指定 depth 参数,则可以更深入(可以使用Infinity来处理所有级别)。

答案 1 :(得分:3)

apply调用等效于使用扩展语法:

[].concat.apply([], a)
[].concat(...a)

它简单地将一个空数组与所有a的值连接起来,将多个参数传递给concat。它只需一步就可以构造一个新数组,这比创建大量中间结果的reduce解决方案效率更高。