数组.slice(0) 是 JavaScript 中创建数组浅拷贝的常用方法!🎯
🔍 基本含义
const arr = [1, 2, 3, 4, 5];
const copy = arr.slice(0); // 创建数组的浅拷贝
console.log(copy); // [1, 2, 3, 4, 5]
slice(0) 的作用:
- 从索引 0 开始,到数组末尾结束
- 返回一个包含所有元素的新数组
- 原数组不会被修改
🎯 与直接赋值的区别
❌ 直接赋值(引用传递)
const original = [1, 2, 3];
const reference = original; // 只是引用,不是拷贝
reference.push(4);
console.log(original); // [1, 2, 3, 4] ❌ 原数组被修改了!
console.log(reference === original); // true
✅ 使用 slice(0)(创建新数组)
const original = [1, 2, 3];
const copy = original.slice(0); // 创建新数组
copy.push(4);
console.log(original); // [1, 2, 3] ✅ 原数组保持不变
console.log(copy); // [1, 2, 3, 4]
console.log(copy === original); // false
🔧 slice() 方法详解
语法:
array.slice(start, end)
不同参数的效果:
const numbers = [1, 2, 3, 4, 5];
numbers.slice(0); // [1, 2, 3, 4, 5] - 完整拷贝
numbers.slice(1); // [2, 3, 4, 5] - 从索引1开始
numbers.slice(1, 3); // [2, 3] - 从索引1到3(不包括3)
numbers.slice(-2); // [4, 5] - 最后2个元素
🚀 在排序函数中的应用
为什么排序前需要拷贝?
// ❌ 危险的排序方式(修改原数组)
function badSort(arr) {
return arr.sort(); // 直接修改原数组!
}
const original = [3, 1, 2];
const sorted = badSort(original);
console.log(original); // [1, 2, 3] ❌ 原数组被修改了!
console.log(sorted); // [1, 2, 3]
✅ 安全的排序方式
// ✅ 安全的排序方式(不修改原数组)
function safeSort(arr) {
return arr.slice(0).sort(); // 先拷贝再排序
}
const original = [3, 1, 2];
const sorted = safeSort(original);
console.log(original); // [3, 1, 2] ✅ 原数组保持不变
console.log(sorted); // [1, 2, 3]
📊 各种拷贝方法的对比
| 方法 | 语法 | 特点 | 深/浅拷贝 |
|---|---|---|---|
| slice(0) | arr.slice(0) |
简洁,性能好 | 浅拷贝 |
| 展开运算符 | [...arr] |
ES6语法,更现代 | 浅拷贝 |
| concat() | [].concat(arr) |
老式方法 | 浅拷贝 |
| Array.from() | Array.from(arr) |
可处理类数组 | 浅拷贝 |
各种拷贝方法示例:
const arr = [1, 2, 3];
// 各种创建浅拷贝的方法
const copy1 = arr.slice(0); // 传统方法
const copy2 = [...arr]; // ES6展开运算符
const copy3 = [].concat(arr); // concat方法
const copy4 = Array.from(arr); // Array.from
// 所有方法都创建了新数组
console.log(copy1 === arr); // false
console.log(copy2 === arr); // false
console.log(copy3 === arr); // false
console.log(copy4 === arr); // false
⚠️ 浅拷贝的局限性
对象数组的浅拷贝问题:
const original = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 }
];
const shallowCopy = original.slice(0);
// 修改拷贝数组中的对象
shallowCopy[0].age = 26;
console.log(original[0].age); // 26 ❌ 原数组中的对象也被修改了!
console.log(shallowCopy[0].age); // 26
解决方案:深拷贝
// 简单的深拷贝方法
const deepCopy = JSON.parse(JSON.stringify(original));
// 或者使用深拷贝函数
function deepClone(arr) {
return arr.map(item => ({ ...item }));
}
✅ 总结
e.slice(0) 就是:
- 📝 创建数组的浅拷贝
- 🛡️ 保护原数组不被修改
- ⚡ 函数式编程的常见模式
- 🎯 排序操作前的标准做法
一句话理解: “先拷贝,再操作,保持原数据不变” 🔒
