如何实现浅拷贝

5 阅读2分钟

浅拷贝(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" - 基本类型,不受影响

何时使用浅拷贝

  1. 性能考虑:浅拷贝比深拷贝更快,内存消耗更少
  2. 共享数据:需要多个对象共享某些引用数据时
  3. 不可变对象:当引用类型是不可变的(如字符串在Java中)
  4. 临时操作:只需要对顶层属性进行操作时

注意事项

  1. 副作用风险:修改浅拷贝对象中的引用类型属性会影响原对象
  2. 循环引用:浅拷贝不会处理循环引用问题
  3. 原型链:JavaScript中某些方法不会复制原型链上的属性

选择使用浅拷贝还是深拷贝取决于具体需求。如果需要完全独立的对象,应该使用深拷贝;如果只是需要对象的副本进行临时操作且不修改嵌套对象,浅拷贝是更高效的选择。