splice和slice

163 阅读2分钟

一、基本定义与语法

方法作用语法
splice修改原数组(增删改元素)array.splice(start, deleteCount, item1, item2, ...)
slice返回新数组(复制部分元素)array.slice(start, end)end 可选,不包含该位置元素)

二、核心区别对比

维度spliceslice
是否修改原数组(返回被删除的元素组成的数组)(返回新数组,原数组不变)
参数含义start:起始位置
deleteCount:删除元素个数
items:插入的新元素
start:起始位置
end:结束位置(不包含)
返回值被删除的元素数组(可能为空)截取的新元素数组(可能为空)
负数索引从数组末尾倒数(如 -1 表示最后一个元素)同上

三、代码示例与场景

1. splice 修改原数组
const arr = [1, 2, 3, 4];

// 删除元素
const removed = arr.splice(1, 2); // 从索引1开始删除2个元素
console.log(arr); // [1, 4]
console.log(removed); // [2, 3]

// 插入元素
arr.splice(1, 0, 5, 6); // 从索引1开始插入5, 6
console.log(arr); // [1, 5, 6, 4]

// 替换元素
arr.splice(2, 1, 7); // 从索引2开始删除1个,插入7
console.log(arr); // [1, 5, 7, 4]
2. slice 返回新数组
const arr = [1, 2, 3, 4];

// 截取部分元素
const newArr = arr.slice(1, 3); // 从索引1到3(不包含3)
console.log(newArr); // [2, 3]
console.log(arr); // 原数组不变:[1, 2, 3, 4]

// 负数索引
const lastTwo = arr.slice(-2); // 截取最后两个元素
console.log(lastTwo); // [3, 4]

四、问题

1. 问:如何复制数组?slice()[...arr] 哪个更好?
    • 两者都可浅复制数组:
      const copy1 = arr.slice(); // 方法1  
      const copy2 = [...arr];    // 方法2(扩展运算符)  
      
    • 性能slice 略快(尤其大数据量时),但差异可忽略。
    • 选择建议:根据场景选择,[...arr] 更灵活(可用于解构赋值)。
2. 问:splice 能否实现数组去重?
    • 理论上可行(遍历数组,发现重复元素时用 splice 删除),但效率低(O(n²))。
    • 推荐方案:用 Setfilter
      const unique = [...new Set(arr)]; // 最简方案  
      
3. 问:slice 如何处理超出边界的索引?
    • start 超过数组长度,返回空数组。
    • end 超过数组长度,自动截取到数组末尾。
    • 示例:
      [1, 2].slice(10); // []  
      [1, 2].slice(0, 100); // [1, 2]  
      
4. 问:splice 插入元素时,deleteCount 为 0 是什么意思?
    • deleteCount=0 表示不删除任何元素,仅在 start 位置插入新元素。
    • 示例:
      [1, 2].splice(1, 0, 3); // 插入3,结果:[1, 3, 2]  
      

五、性能与最佳实践

  1. 性能对比

    • slice:O(n)(复制元素)。
    • splice:O(n)(删除元素后需移动后续元素)。
    • 注意:频繁使用 splice 可能导致性能问题(如循环中删除元素)。
  2. 替代方案

    • 若需避免修改原数组,可用 filter 替代 splice
      // 删除索引1的元素(不修改原数组)  
      const newArr = arr.filter((_, index) => index !== 1);  
      
  3. 边界检查

    • 使用 splice 前建议检查索引合法性,避免意外修改:
      if (start >= 0 && start <= arr.length) {  
        arr.splice(start, deleteCount);  
      }