有多个数组a, b, c,需求是将多个数组合并成一个:
let a = [1, 2, 3];
let b = [4, 5, 6];
let c = [7, 8, 9];
1. concat()
合并多个数组,不影响原数组(会造成内存浪费),不能处理嵌套数组。
const r = a.concat(b);
a; // [1, 2, 3]
b; // [4, 5, 6]
r; // [1, 2, 3, 4, 5, 6]
如果 a 数组有10000个元素, b 数组也有有10000个元素, 那么数组r就有20000个元素, 这种方式占用了2倍的内存。a = b = null;
就会被垃圾回收机制回收。
2. 基于for循环 - push()
没有concat的内存浪费,看上去土而且不好维护, 只能合并两个数组,会改变原数组,不能处理嵌套数组。
for(let i in b) {
a.push(b[i]);
}
a; // [1, 2, 3, 4, 5, 6]
b; // [4, 5, 6]
3. apply
简洁高效,能实现多个数组合并, 会改变原数组, 并且能够实现深度嵌套。
a.push.apply(a, b);
a; // [1, 2, 3, 4, 5, 6]
b; // [4, 5, 6]
4. 更优美的push
多个数组合并, 会改变原数组, 效率比较高
// es6
a.push(...b, ...c)
a; // [1, 2, 3, 4, 5, 6]
b; // [4, 5, 6]
c; // [7, 8, 9];
为什么 Array.concat
这么慢?
合并拥有大小为 10 的数组 10000 次,.concat
的速度为 0.40 ops/sec(操作每秒),而 .push
的速度是 378 ops/sec。也就是说 push
比 concat
快了整整 945 倍!这种差异可能不是线性的,但在这种小规模数据量上已经很明显了。
这与它们的运行机制有很大的关系:在合并数组的时候,.concat
创建了一个新的数组,而 .push
只是修改了第一个数组。这些额外的操作(将第一个数组的元素添加到返回的数组里)就是拖慢了 .concat
速度的关键。