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

Cur*_*rly 3 javascript

我基本上已经记住了这一点,[].concat.apply([], a)以使未深度嵌套的数组变平,但我不完全了解它的工作原理。例如,这apply涉及到什么?

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

T.J*_*der 5

有两个方面:

concat 将您传递到其中的数组展平(到一个级别),仅包括它们在结果数组中的元素:

console.log([1, 2, 3].concat(4, 5, [6, 7, 8]));
Run Code Online (Sandbox Code Playgroud)

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

applyFunction.prototype.apply:你可以用它来调用一个函数指定什么this应该和该函数作为数组提供的参数。最后一点是关键:数组的元素传递给concat离散参数,如果任何这些是数组,concat提取它们的内容。所以

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

...调用concatthis被阵列(2)中,在传递的参数[1, 2, 3]45,和[6, 7, 8]。(数组(1)仅用于get concat,然后被丢弃。)

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

但是在现代JavaScript中,您可能需要改为使用flatpolyfill:

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

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

请注意,flat可选地进行递归展平。默认情况下,它仅执行一个级别(如concat),但是如果指定depth参数,则可以更深入(可以使用Infinity来处理所有级别)。


Ber*_*rgi 5

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

[].concat.apply([], a)
[].concat(...a)
Run Code Online (Sandbox Code Playgroud)

它只是将一个空数组与 的所有值连接起来a,将多个参数传递给concat。它在一个步骤中构建一个新数组,这比reduce创建大量中间结果的解决方案更有效。