esp*_*spc 4 javascript deep-copy shallow-copy
几天来我对浅拷贝和深拷贝的真正定义感到非常困惑。
\n当我阅读浅拷贝的 mdn 文档(https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy)时,这一切都有意义。第一段清楚地解释了什么是浅拷贝。文档说
\n\n\n对象的浅拷贝是其属性与从中创建副本的源对象共享相同引用(指向相同基础值)的副本。因此,当您更改源或副本时,也可能导致其他对象也发生更改\xe2\x80\x94,因此,您最终可能会无意中导致对源或副本进行您不希望的更改\'预计。
\n
我完全明白了那部分。根据我的理解,下面的代码示例是浅复制的示例,因为更改源或副本也会导致另一个对象发生更改。
\nlet a = {\n food: "pasta",\n restaurantName: "myPastPlace"\n}\n\nlet b = a\n\nb.food = "hamburger"\n\nconsole.log(b.food) //hamburger\nconsole.log(a.food) //hamburger\nRun Code Online (Sandbox Code Playgroud)\n所以,令人困惑的部分是当我使用扩展语法来制作副本时。这是深拷贝还是浅拷贝?因为对于我来说,对于第一级深度来说,扩展语法(运算符)正在制作深度复制。然而,MDN 文档表示扩展语法创建的是浅拷贝而不是深拷贝。
\n\n\n在 JavaScript 中,所有标准内置对象复制操作(扩展语法、Array.prototype.concat()、Array.prototype.slice()、Array.from()、Object.assign() 和 Object.create() )创建浅拷贝而不是深拷贝。
\n
let a = {\n food: "pasta",\n restaurantName: "myPastPlace"\n}\n\nlet b = {...a}\nconsole.log(b)\n\nb.food = "hamburger"\n\nconsole.log(b.food) //hamburger\nconsole.log(a.food) //pasta\n\nRun Code Online (Sandbox Code Playgroud)\n
变量可以包含一个值(在原始值的情况下,如1)或引用(在对象的情况下,如 ){ food: "pasta" }。原始类型只能被复制,并且由于它们不包含属性,因此不存在浅/深区别。
如果您将引用本身视为原始值,则 是引用b = a的副本。但由于 JavaScript 不允许您直接访问引用(就像 C 那样,其中等效的概念是指针),因此将复制引用称为“复制”会产生误导和混淆。在 JavaScript 上下文中,“复制”是值的副本,引用不被视为值。
对于非原始值,存在三种不同的情况:
\nb = a仅指向同一个对象;如果您a以任何方式进行修改,b都会受到同样的影响。直觉上你会说无论你修改哪个对象都会反映在副本中,但这是错误的:没有副本,只有一个对象。无论您从哪个引用访问对象,它都是同一个实体。这就像打皮特先生一巴掌,然后想知道为什么布拉德对你生气\xe2\x80\x94 布拉德和皮特先生是同一个人,而不是克隆人。let a = {\n food: "pasta",\n contents: {\n flour: 1,\n water: 1\n }\n}\nlet b = a;\na.taste = "good";\na.contents.flour = 2;\nconsole.log(b);Run Code Online (Sandbox Code Playgroud)\r\nb.contents.flour受到 的更改的影响a(因为b.contents和a.contents引用同一个对象{ flour: 1, water: 2 }),但a.taste它不存在(因为a和b本身就是对象)。let a = {\n food: "pasta",\n contents: {\n flour: 1,\n water: 1\n }\n}\nlet b = {...a};\na.taste = "good";\na.contents.flour = 2;\nconsole.log(b);Run Code Online (Sandbox Code Playgroud)\r\nb.taste都b.contents.flour不受 变化的影响a。let a = {\n food: "pasta",\n contents: {\n flour: 1,\n water: 1\n }\n}\nlet b = structuredClone(a);\na.taste = "good";\na.contents.flour = 2;\nconsole.log(b);Run Code Online (Sandbox Code Playgroud)\r\n请注意,此时structuredClone还很新;如果任何用户使用旧版浏览器,您可能需要使用 polyfill。
| 归档时间: |
|
| 查看次数: |
2295 次 |
| 最近记录: |