- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
几天来我对浅拷贝和深拷贝的真正定义感到非常困惑。
当我阅读关于浅拷贝的 mdn 文档 ( https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy ) 时,这一切都说得通了。第一段清楚地解释了什么是浅拷贝。文档说
A shallow copy of an object is a copy whose properties share the same references (point to the same underlying values) as those of the source object from which the copy was made. As a result, when you change either the source or the copy, you may also cause the other object to change too — and so, you may end up unintentionally causing changes to the source or copy that you don't expect.
我完全明白了那部分。根据我的理解,下面的代码示例是浅拷贝的示例,因为更改源或副本会导致其他对象也发生更改。
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, all standard built-in object-copy operations (spread syntax, Array.prototype.concat(), Array.prototype.slice(), Array.from(), Object.assign(), and Object.create()) create shallow copies rather than deep copies.
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
最佳答案
一个变量可以包含一个值(如果是原始值,比如 1
),或者一个引用(如果是对象,比如 { food: "pasta" }
)。原始类型只能被复制,因为它们不包含任何属性,不存在浅/深之分。
如果您将引用本身视为原始值,b = a
是一份引用。但是由于 JavaScript 不让您直接访问引用(就像 C 那样,其中等效的概念是指针),将复制引用称为“复制”是一种误导和混淆。在 JavaScript 上下文中,“复制”是一个值的副本,引用不被视为值。
对于非原始值,存在三种不同的场景:
b = a
创建, 仅仅指向同一个对象;如果你修改 a
无论如何,b
以同样的方式受到影响。直觉上你会说无论你修改哪个对象都会反射(reflect)在副本中,但这是错误的:没有副本,只有一个对象。无论您从哪个引用访问对象,它都是同一个实体。这就像扇皮特先生耳光,并想知道布拉德为什么生你的气 — 布拉德和皮特先生是同一个人,而不是克隆人。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);
b.taste
和 b.contents.flour
不受 a
变化的影响.let a = {
food: "pasta",
contents: {
flour: 1,
water: 1
}
}
let b = structuredClone(a);
a.taste = "good";
a.contents.flour = 2;
console.log(b);
注意此时structuredClone
还是很新的;如果任何用户使用旧版浏览器,您可能需要使用 polyfill。
关于javascript - Spread Syntax 创建的是浅拷贝还是深拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72209243/
免责声明 这篇文章是关于术语“浅拷贝”和“深拷贝”的正确用法,特别是在谈论复制一个不包含任何引用的对象时。这个问题并不意味着(也不应该)基于意见,除非真的没有关于这个话题的共识。我已将此问题标记为 C
我有这个功能 int getrelation(string name, RELATION& output){ bool found=0; int index=0;
与 why should I make a copy of a data frame in pandas 有关 我注意到在流行的backtesting图书馆, def __init__(self, d
我的问题很基础,但我想 100% 理解所有内容。 SO中的很多问题都引用了我的帖子,但我没有找到满意的答案。 我们知道java中的枚举是引用类型。让我们考虑以下片段: public static cl
请引用这个 fiddle 的问题。 http://jsfiddle.net/AQR55/ 1)为什么附加到隔离范围属性的 watch - 双向绑定(bind)到父属性,不会在更改父范围属性时触发。 在
我想使用 UP3 来完成一项非常具体的任务,我应该能够使用 API 来实现该任务。我想了解是否可以编写以下应用程序。 基于https://jawbone.com/support/articles/00
如何在辅助方法中传递上下文并提取数据? 请参阅以下代码片段: import AppContext from '../../context/AppContext' import extractDatta
我正在尝试使用 simple-git 创建浅克隆。我正在尝试创建与此命令等效的命令:git clone --depth 1 https://github.com/steveukx/git-js.git
我是一名优秀的程序员,十分优秀!