浅拷贝(Shallow Copy)是创建一个新对象,并复制原始对象的顶层属性值。如果属性是基本类型,则复制值;如果是引用类型,则复制引用(内存地址),新旧对象会共享这些引用类型的属性。
常见编程语言中的实现方法
1. JavaScript/TypeScript
对象浅拷贝
// 方法1: 扩展运算符(最常用)
const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };
// 方法2: Object.assign()
const shallowCopy2 = Object.assign({}, original);
// 方法3: 循环复制
const shallowCopy3 = {};
for (let key in original) {
if (original.hasOwnProperty(key)) {
shallowCopy3[key] = original[key];
}
}
数组浅拷贝
// 方法1: 扩展运算符
const originalArray = [1, 2, { a: 3 }];
const shallowArray = [...originalArray];
// 方法2: slice()
const shallowArray2 = originalArray.slice();
// 方法3: Array.from()
const shallowArray3 = Array.from(originalArray);
// 方法4: concat()
const shallowArray4 = originalArray.concat();
浅拷贝 vs 深拷贝
示例对比
const original = {
name: "Alice",
scores: [85, 90, 95], // 引用类型
address: { // 引用类型
city: "Beijing",
street: "Main St"
}
};
// 浅拷贝
const shallowCopy = { ...original };
// 修改浅拷贝对象的引用类型属性
shallowCopy.scores.push(100);
shallowCopy.address.city = "Shanghai";
console.log(original.scores); // [85, 90, 95, 100] - 被影响了!
console.log(original.address.city); // "Shanghai" - 被影响了!
console.log(original.name); // "Alice" - 基本类型,不受影响
何时使用浅拷贝
- 性能考虑:浅拷贝比深拷贝更快,内存消耗更少
- 共享数据:需要多个对象共享某些引用数据时
- 不可变对象:当引用类型是不可变的(如字符串在Java中)
- 临时操作:只需要对顶层属性进行操作时
注意事项
- 副作用风险:修改浅拷贝对象中的引用类型属性会影响原对象
- 循环引用:浅拷贝不会处理循环引用问题
- 原型链:JavaScript中某些方法不会复制原型链上的属性
选择使用浅拷贝还是深拷贝取决于具体需求。如果需要完全独立的对象,应该使用深拷贝;如果只是需要对象的副本进行临时操作且不修改嵌套对象,浅拷贝是更高效的选择。