几天来,对于浅薄和深拷贝的真正定义,我感到非常困惑。
当我在浅拷贝上读取mdn文档(https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy)时,这一切都是有意义的。第一段清楚地解释了什么是浅薄的复制品。医生说
对象的浅拷贝是一个副本,其属性与复制所用的源对象的引用(指向相同的基础值)相同。因此,当您更改源或副本时,还可能导致其他对象也发生更改--因此,您可能会无意中导致对源或副本的更改,这是您所不期望的。
我完全明白那部分。根据我的理解,下面的代码示例是浅拷贝的示例,因为更改源或副本会导致其他对象也发生更改。
let a = {
food: "pasta",
restaurantName: "myPastPlace"
}
let b = a
b.food = "hamburger"
console.log(b.food) //hamburger
console.log(a.food) //hamburger
所以,令人困惑的地方是,当我使用扩展语法来复制时。这是深拷贝还是浅拷贝?因为对于第一层深度,对我来说,扩展语法(操作符)正在进行深度复制。然而,MDN文档表示,扩展语法创建了一个浅拷贝,而不是深拷贝。
In JavaScript,所有标准的内置对象复制操作(扩展语法、Array.prototype.concat()、Array.prototype.slice()、Array.from()、Object.assign()和Object.create())都创建浅拷贝而不是深拷贝。
let a = {
food: "pasta",
restaurantName: "myPastPlace"
}
let b = {...a}
console.log(b)
b.food = "hamburger"
console.log(b.food) //hamburger
console.log(a.food) //pasta
发布于 2022-05-12 02:20:54
变量可以包含一个值(在原始值的情况下,比如1
),也可以包含一个引用(对于对象,比如{ food: "pasta" }
)。基元类型只能复制,而且由于它们不包含属性,因此不存在浅/深区分。
如果将引用本身视为原语值,则b = a
是引用的副本。但是,由于JavaScript不允许您直接访问引用(就像C一样,等效的概念是指针),将引用复制为“复制”是误导和混淆的。在JavaScript上下文中,“复制”是值的副本,而引用不被视为值。
对于非原始值,有三种不同的方案:
b = a
创建)仅指向同一个对象;如果以任何方式修改a
,则b
将受到相同的影响。直观地,您会说,您修改的任何对象都反映在副本中,但这是错误的:没有副本,只有一个对象。不管您从哪个引用访问对象,它都是同一个实体。这就像扇皮特的耳光,想知道为什么布拉德会生你的气--布拉德和皮特是同一个人,而不是克隆人。--
let a = {
food: "pasta",
contents: {
flour: 1,
water: 1
}
}
let b = a;
a.taste = "good";
a.contents.flour = 2;
console.log(b);
b.contents.flour
受到a
中的更改的影响(因为b.contents
和a.contents
引用相同的对象{ flour: 1, water: 2 }
),但是a.taste
并不存在(因为a
和b
本身就是对象)。
let a = {
food: "pasta",
contents: {
flour: 1,
water: 1
}
}
let b = {...a};
a.taste = "good";
a.contents.flour = 2;
console.log(b);
a
.的变化不影响b.taste
和b.contents.flour
let a = {
food: "pasta",
contents: {
flour: 1,
water: 1
}
}
let b = structuredClone(a);
a.taste = "good";
a.contents.flour = 2;
console.log(b);
请注意,此时structuredClone
仍然是非常新的;如果有任何用户正在使用旧的浏览器,则可能需要使用多边形填充。
发布于 2022-05-12 01:54:45
扩展操作符允许您做一个浅拷贝。若要进行深度复制,请使用structuredClone()
方法。
所以在你的例子中,它看起来是这样的:
let a = {
food: "pasta",
restaurantName: "myPastPlace"
}
let b = structuredClone(a);
阅读更多:https://developer.mozilla.org/en-US/docs/Web/API/structuredClone
https://stackoverflow.com/questions/72209243
复制相似问题