gpt4 book ai didi

javascript - ES6 React - 引用、浅拷贝和深拷贝有什么区别以及如何比较它们?

转载 作者:数据小太阳 更新时间:2023-10-29 04:48:54 30 4
gpt4 key购买 nike

我知道这个问题已经被讨论了很多次,我想我已经有了一个基本的想法。我从 StackOverflow 找到了一些评分最高的答案:

但所有的答案对我来说似乎都很模糊。
让我们考虑以下示例:

const user = {
name: "James",
age: 33,
highlights: {
career: "Basketball player",
NBAChampion: [2012, 2013, 2016],
},
promotion: () => ("Get LeBron15 now!"),
};

const james = user;
const clone = { ...user };
const clone2 = Object.assign({}, user);
const clone3 = JSON.parse(JSON.stringify(user));
const clone4 = {
...user,
highlights: {
...user.highlights,
// I comment the it out, so now NBAChampion is a reference rather than copy!
// NBAChampion: [...user.highlights.NBAChampion]
}
};

user.age++;
user.highlights.career = "football player";

console.log('james', james, james === user, james == user);
console.log('clone', clone, clone === user, clone == user);
console.log('clone2', clone2, clone2 === user, clone2 == user);
console.log('clone3', clone3, clone3 === user, clone3 == user);
// console.log(clone3.promotion()); // My problem with clone3 is that function's been removed.
console.log('clone4', clone4, clone4 === user, clone4 == user);

  • james 是一个引用,它始终与用户完全相同;
  • clone 是一个副本。 是浅拷贝还是深拷贝?nameageuser是分开的,但是 >highlights 还是一个引用。
  • clone2 的行为与 clone 完全相同。
  • clone3 由字符串转换而来。 它是深拷贝吗?它不是完美的克隆,因为函数(如果有的话)不会保存以这种方式转换。
  • clone4 复制了 user 的每一层,所以我可以称之为“深复制”。
    但是,如果展开运算符只是有时创建深拷贝,那么我如何测试新对象是否是深拷贝?<

更新:我在clone4中注释掉了NBAChampion,所以现在NBAChampion是一个引用而不是复制!如果我在 user.highlights.NBAChampion 中推送一个新值,clone4 也会更新。
我们应该怎么称呼这种类型的对象?它既不是浅拷贝也不是深拷贝。


为什么这很重要?

React 有一个比较浅拷贝的 shouldComponentUpdate() 函数。有 link .
在 react 中 source code (Line: 356)浅比较是这样完成的:

shouldComponentUpdate(nextProps) {
return this.props.children !== nextProps.children;
}

在上面的代码演示中,console.log 中的第二个和第三个参数显示了cloneuser 之间的比较结果。但是,只有第一个副本返回 true。 (注意:严格比较和抽象比较没有区别)

如果我将 shouldComponentUpdate 应用于上面的演示,显然只有 jamesuser 会返回 true。所以 james 是 Facebook 代码中的一个浅拷贝。那么我的问题是:

  • 在 JS 中引用和浅拷贝是一回事吗?如果不是,为什么 React 会这样做?
  • 如何在我的测试用例中测试一个对象是浅拷贝还是深拷贝?

这个问题花了我很多时间来制作。欢迎任何带有示例的清晰解释。
非常感谢。

最佳答案

Let's consider the example below

cloneclone2 很浅,只影响原始对象的属性。 clone3clone4 很深。

However if the spread operator only creates deep copy sometimes, then how can I test if the new object is a deep copy or not?

它在 clone4 的情况下创建深拷贝 - 只要深度由开发人员控制。通常,在 React 中不需要测试对象是否是深拷贝或只是不同,因为这种检查代价高昂,并且需要遍历两个比较对象中的嵌套对象并逐个属性地比较它们。

性能是 React 依赖不变性的原因。如果新值 === 不相等,则将其视为不同的值。

So james is a shallow copy in Facebook's code.

事实并非如此。它是分配给另一个变量的引用。它仍然是同一个对象。

Are reference and shallow copy exactly the same thing in JS?

引用不是副本。所以它也不是浅拷贝。

I commented NBAChampion out in clone4, so now NBAChampion is a reference rather than copy! If I push a new value in user.highlights.NBAChampion, clone4 will also updates. What should we call this type of object? It's neither a shallow nor deep copy.

这只是一个副本。它没有特定的名称,因为很少需要进行这种选择性复制。如果意图是让它表现得像深拷贝,那应该被称为错误。

关于javascript - ES6 React - 引用、浅拷贝和深拷贝有什么区别以及如何比较它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49465712/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com