大话前端:深拷贝与浅拷贝

2023-12-16 05:35:16

让我们使用以下比喻来解释深拷贝与浅拷贝:

  1. 浅拷贝(复制写有房子地址的书本)

    • 想象一下,你有一本书,里面记录了各种房子的地址。这些地址指向具体的房子,就像变量在计算机中指向内存中的对象。当你进行浅拷贝时,相当于复制了这本书,包括其中的所有地址。但重要的是,这些复制出来的地址仍然指向原来的那些房子。也就是说,原本的书和复制的书中的地址都指向同一个实际的房子(对象)。如果这个房子(对象)发生了变化,那么无论你是通过原本的书还是复制的书查看地址,看到的都将是同一个已经变化的房子。
  2. 深拷贝(复制房子并记录新地址)

    • 深拷贝则是你不仅复制了记录地址的书本,还去实际复制了每个地址所指的房子。这样,你的新书中的地址将指向这些全新复制出来的房子。这些新房子虽然在外观和结构上与原来的房子相同,但它们是完全独立的实体。在这种情况下,如果你更改了任一本书中某个地址所指的房子,另一本书中相同地址所指的原始房子不会受到任何影响。

区别与用处:

  • 区别:浅拷贝只复制了记录对象引用的“书本”,但没有复制引用的实际对象;深拷贝不仅复制了“书本”,还复制了所有书中记录的对象。
  • 用处
    • 浅拷贝适用于当你只需要复制对象的顶层结构,而不关心内部数据是否共享时。它在处理大型对象或需要快速复制时非常有效。
    • 深拷贝适用于需要完全独立副本的场合,尤其是当你需要修改副本对象而不影响原始对象时。

在实际编程中,理解浅拷贝和深拷贝的区别对于管理数据和避免潜在的错误至关重要。

在JavaScript中,深拷贝和浅拷贝可以通过简单的示例来具体说明。首先,让我们创建一个对象,然后展示如何进行浅拷贝和深拷贝。

示例对象:

let originalObject = {
    name: "Alice",
    address: {
        city: "Wonderland",
        street: "Rabbit Hole 42"
    }
};

这个对象有两个属性:一个是基本类型的(name),另一个是引用类型的(address)。

浅拷贝示例:

在JavaScript中,浅拷贝可以通过 Object.assign 或者展开运算符(...)实现。

// 使用 Object.assign
let shallowCopy1 = Object.assign({}, originalObject);

// 使用展开运算符
let shallowCopy2 = { ...originalObject };

// 修改浅拷贝对象中的嵌套对象
shallowCopy1.address.city = "Paris";

console.log(originalObject.address.city); // 输出: "Paris"
console.log(shallowCopy2.address.city); // 输出: "Paris"

在这个例子中,修改 shallowCopy1address.city 也会影响到 originalObject,因为它们共享同一个 address 对象。

深拷贝示例:

深拷贝通常可以通过 JSON.parseJSON.stringify 实现,或者使用更复杂的函数来递归复制每个属性。

let deepCopy = JSON.parse(JSON.stringify(originalObject));

// 修改深拷贝对象中的嵌套对象
deepCopy.address.city = "London";

console.log(originalObject.address.city); // 输出: "Paris"
console.log(deepCopy.address.city); // 输出: "London"

在这里,deepCopyoriginalObject 的一个完全独立的副本。修改 deepCopy 不会影响 originalObject

注意事项:

  • 使用 JSON.parse(JSON.stringify(object)) 进行深拷贝只适用于可以序列化为JSON的对象。对于包含函数、undefined、或循环引用的对象,这种方法不适用。
  • 更复杂的对象可能需要自定义的深拷贝逻辑,或使用专门的库来处理深拷贝。

文章来源:https://blog.csdn.net/weixin_43903608/article/details/134916031
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。