一、基本定义与语法
| 方法 | 作用 | 语法 |
|---|---|---|
splice | 修改原数组(增删改元素) | array.splice(start, deleteCount, item1, item2, ...) |
slice | 返回新数组(复制部分元素) | array.slice(start, end)(end 可选,不包含该位置元素) |
二、核心区别对比
| 维度 | splice | slice |
|---|---|---|
| 是否修改原数组 | 是(返回被删除的元素组成的数组) | 否(返回新数组,原数组不变) |
| 参数含义 | 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²))。 - 推荐方案:用
Set或filter: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]
五、性能与最佳实践
-
性能对比
slice:O(n)(复制元素)。splice:O(n)(删除元素后需移动后续元素)。- 注意:频繁使用
splice可能导致性能问题(如循环中删除元素)。
-
替代方案
- 若需避免修改原数组,可用
filter替代splice:// 删除索引1的元素(不修改原数组) const newArr = arr.filter((_, index) => index !== 1);
- 若需避免修改原数组,可用
-
边界检查
- 使用
splice前建议检查索引合法性,避免意外修改:if (start >= 0 && start <= arr.length) { arr.splice(start, deleteCount); }
- 使用