JavaScript 中的浅拷贝与深拷贝

JavaScript 根据数据类型的不同,以两种方式处理拷贝。

基本类型(按值拷贝)

基本类型包括 string、number、boolean、symbol、bigInt 和 null。 当你拷贝一个基本类型时,JavaScript 会在内存中创建一个新的独立版本。

示例:

let a = 10;
let b = a;
b = 20;

结果: a 仍为 10。

非基本类型(按引用拷贝)

对象和数组的工作方式不同。它们使用引用。 当你拷贝一个对象时,你只是拷贝了它在内存中位置的指针。

示例:

let original = { name: "YOO" };
let copy = original;
copy.name = "NEW";

结果: original.name 现在是 "NEW"。

区别:浅拷贝 vs 深拷贝

浅拷贝只拷贝对象的第一层。如果对象包含嵌套对象,它仍然指向原始的嵌套引用。 深拷贝则会创建一个包含所有新值的新对象。

可以把它想象成披萨:

  • 浅拷贝:你和朋友共用一个披萨。如果你的朋友吃掉了一块,你的披萨也会随之变小。
  • 深拷贝:你们各自拥有独立的披萨。如果你的朋友吃掉了一块,你的披萨保持不变。

浅拷贝方法

你可以使用展开运算符 (...) 来进行浅拷贝。

let original = { name: "YOO", details: { age: 22 } };
let copy = { ...original };

警告: 如果你修改了 original.details.agecopy.details.age 也会随之改变。这就是浅拷贝的陷阱。

深拷贝方法

1. structuredClone()

这是现代浏览器和 Node.js 中的内置函数。它能完美处理嵌套结构。

优点:

  • 快速且原生。
  • 支持 DateRegExpMap

缺点:

  • 如果对象包含函数或 DOM 节点,则会失败。

2. JSON.parse(JSON.stringify())

这是一种老技巧,即将对象转换为字符串,然后再转回对象。

为什么应避免使用:

  • 它会丢失 undefinedMapSetInfinity 等数据。
  • 它可能会损坏某些值。

来源: https://dev.to/yogesh_992/shallow-copy-vs-deep-copy-in-java-script-explained-in-easiest-way-3dg5