返回

揭秘JS中的Ctrl+C:理解深拷贝与浅拷贝背后的世界

前端

深拷贝与浅拷贝是JavaScript中的两个重要概念,理解它们对于编写高质量代码至关重要。浅拷贝只复制原始对象的引用,而深拷贝则复制原始对象及其所有属性和子属性。这两种拷贝方式有着不同的应用场景,也存在着各自的优缺点。

浅拷贝

浅拷贝在JavaScript中通常使用Object.assign()方法来实现。它会将源对象的可枚举属性复制到目标对象,但不会复制源对象的原型链或子属性。

const obj1 = {
  name: "John",
  age: 30,
  address: {
    street: "123 Main St",
    city: "New York",
  },
};

const obj2 = Object.assign({}, obj1);

console.log(obj2);
// { name: 'John', age: 30, address: { street: '123 Main St', city: 'New York' } }

在上面的示例中,obj2是一个浅拷贝obj1的对象。这意味着obj2具有与obj1相同的属性值,但它们指向不同的内存地址。更改obj2的属性值不会影响obj1,反之亦然。

深拷贝

深拷贝会复制源对象的所有属性和子属性,无论它们位于何处。这可以通过使用库函数或手动实现。

使用库函数进行深拷贝

以下是一些可以用来实现深拷贝的库函数:

  • lodash.cloneDeep()
  • jQuery.extend(true, {}, obj1)
  • JSON.parse(JSON.stringify(obj1))

手动实现深拷贝

也可以手动实现深拷贝,但这是一个递归过程,可能比较复杂。以下是手动实现深拷贝的步骤:

  1. 创建一个新的对象。
  2. 遍历源对象的属性。
  3. 如果属性是一个简单类型,则将其复制到新对象。
  4. 如果属性是一个复杂类型,则递归调用深拷贝函数来复制它。
  5. 将新对象返回。
function deepCopy(obj) {
  if (typeof obj !== "object" || obj === null) {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  }

  const newObj = {};
  for (const key in obj) {
    newObj[key] = deepCopy(obj[key]);
  }

  return newObj;
}

浅拷贝与深拷贝的比较

特征 浅拷贝 深拷贝
复制方式 只复制原始对象的引用 复制原始对象及其所有属性和子属性
内存地址 源对象和目标对象指向不同的内存地址 源对象和目标对象指向相同的内存地址
更改属性值的影响 更改目标对象的属性值不会影响源对象 更改目标对象的属性值会影响源对象
性能 较快 较慢
适用场景 当需要快速复制对象时 当需要确保复制的对象与源对象完全独立时

总结

深拷贝与浅拷贝是JavaScript中两种重要的拷贝方式,它们有着不同的应用场景和优缺点。在实际开发中,需要根据具体情况选择合适的拷贝方式。