合并数组用 concat 还是 扩展运算符比较好?

let arr1 = [1, 2];
let arr2 = [3, 4];
// concat
arr1 = arr1.concat(arr2);
// 扩展运算符
arr1 = [...arr1, ...arr2];
// 或者
arr1.push(...arr2);

哪种更好,为什么?性能?

阅读 9.2k
3 个回答

究竟用哪种还是得根据你实际需求来的

concates5时就有的,优点是兼容性高,不需要转译
...es6新出的语法,简化了写法,代码看上去更简洁直观,但实际只是做了封装,底层还是用的原来的方法,如下为babel转译的结果

第二种写法

arr1 = [...arr1, ...arr2];
  ↓ 相当于
function _toConsumableArray(arr) {
 if (Array.isArray(arr)) { 
   for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; 
   } else { return Array.from(arr); }
}
arr1 = [].concat(_toConsumableArray(arr1), arr2);

第三种写法

arr1.push(...arr2);
  ↓ 相当于
arr1.push.apply(arr1, arr2);

再来看三种写法处理不同数据量的时间(数据分别为1,10,100) 单位:万

num:10000
 s1: 0.01813671875ms
 s2: 0.1808984375ms
 s3: 0.078857421875ms

num:100000
 s1: 0.8310546875ms
 s2: 10.428955078125ms
 s3: 8.025146484375ms

num:1000000
s1: 11.42724609375ms
s2: 83.867919921875ms
s3: Maximum call stack size exceeded

总结:
concat性能最优
在数据量极小时三者差异并不大
在数据有一定量时concat性能遥遥领先于 arr1 = [...arr1, ...arr2]arr1.push(...arr2)
在数据过大时第三种方法会因为apply的特点由于数据量过大导致堆栈溢出

先看下你说的这三种方式的差别:

这个差别的话存在俩中环境中:

  • 第一种,你的实际使用环境还是es5的环境,那么你转一下看看babel怎么处理的;

你用babel转成es5看看扩展运算符

[...arr1, ...arr2] ==> [].concat(arr1, arr2)

arr1.push(...arr2) ==> arr1.push.apply(arr1, arr2)

这种差别的情况下可以看到,
好处:扩展运算符看起来更直观,可读性更好,调用的api更少,简洁。
性能:可能需要你做一下评估,我没做这个,

  • 第二种: 你的实际使用环境已经支持了扩展运算符,就是说原生实现了这个操作符,那么

好处: 大家都用这个,提升你在其他前端心中的形象,你是一个与时俱进的人,不会被淘汰。。。
性能: 找支持这个语法的环境去测一下,比如node环境

另外说一下,性能的话,你也可以通过一些常用的比较方法来判断。
比如可以通过对一个数组连接10000万个元素看看不同方式花费的时间,去评估一下;
这个事情你自己可以做一下。

第二种写法创建了个新数组,(无论js引擎如何优化扩展运算符)性能肯定会差
第三种写法因为push是递归的,所以性能也差(数据太多还会报错)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题