JavaScript 中的浅拷贝和深拷贝

2025 年 1 月 7 日 | 阅读 3 分钟

在 JavaScript 中,有两种复制对象的方式:浅拷贝深拷贝。理解这两种复制方式的区别在很多编程场景中都很重要,因为它们各有优缺点。

浅拷贝

浅拷贝 是一种只复制一层深度的拷贝。换句话说,它复制对象及其所有属性,但任何嵌套的对象或数组仍然会引用与原始对象相同的内存位置。这意味着,如果你修改了嵌套对象,它也会影响原始对象以及被复制的对象。

以下是使用扩展运算符浅拷贝对象的示例:

在此示例中,originalObject 有一个嵌套对象 b,其中有一个属性 c。扩展运算符 ... 用于创建一个新对象 shallowCopy,它是 originalObject 的浅拷贝。这意味着如果我们修改 shallowCopy,它不会影响 originalObject。

如你所见,修改 shallowCopy 上的属性 a 的值不会影响 originalObject。然而,修改嵌套对象 b 上的属性 c 的值会同时影响 shallowCopy 和 originalObject。

这是因为 shallowCopy 和 originalObject 都引用了同一个嵌套对象 b。当我们修改 shallowCopy 上的 b 时,它会修改 originalObject 上的同一个对象。

深拷贝

深拷贝 是一种创建新对象,并为所有属性和嵌套对象或数组创建新内存位置的拷贝。这意味着,如果你修改了被复制的对象或其任何嵌套对象或数组,它不会影响原始对象。

以下是使用 JSON.parse()JSON.stringify() 方法深拷贝对象的示例:

在此示例中,我们使用 JSON.stringify() 将 originalObject 转换为 JSON 字符串,然后使用 JSON.parse() 将该字符串转换回新对象 deepCopy。这会创建一个 originalObject 的深拷贝。

现在,如果我们修改 deepCopy,它不会影响 originalObject:

如你所见,修改 deepCopy 上的属性 a 或嵌套对象 b 的值不会影响 originalObject。这是因为 deepCopy 和 originalObject 对它们的所有属性和嵌套对象都有单独的内存位置。

性能考虑

需要注意的是,深拷贝在性能方面可能比浅拷贝更昂贵。这是因为创建新对象并复制其所有属性和嵌套对象可能比仅仅创建引用与原始对象相同内存位置的新对象花费更多的时间和内存。

在某些情况下,浅拷贝可能更有效和实用。然而,如果你需要确保修改被复制的对象不会影响原始对象,那么深拷贝是必需的。

结论

在 JavaScript 中,有两种复制对象的方式:浅拷贝和深拷贝。浅拷贝创建一个新对象,它引用与原始对象相同的内存位置,而深拷贝创建一个新对象,并为其所有属性和嵌套对象或数组创建新的内存位置。

浅拷贝在性能方面可能更有效,但如果修改被复制的对象会影响原始对象,可能会导致意外行为。深拷贝确保修改被复制的对象不会影响原始对象,但可能在性能方面更昂贵。

虽然使用 JSON.parse()JSON.stringify() 是创建对象深拷贝的简便方法,但它并非在所有情况下都有效。如果你需要创建对象的深拷贝,使用 JSON.parse()JSON.stringify() 是一个简单的选择。但是,如果正在复制的对象包含函数或循环引用,则可能需要一个递归的深拷贝函数。