JavaScript 什么是浅拷贝
浅拷贝: 在浅拷贝的情况下,当我们将原始对象复制到克隆对象时,克隆对象具有原始对象的内存地址的副本。意味着两者指向相同的内存地址。
原始对象和克隆对象在内部都指向相同的引用对象。由于它们指向相同的内存地址,因此如果更改克隆对象,更改将反映在原始对象上,因为它们指向相同的内存地址。
Javascript
<script>
var obj1 = {
id: 1,
company: "GFG"
};
var obj2 = obj1;
obj2.id = 2;
console.log(obj1.id);
console.log(obj2.id);
</script>
输出:
2
2
解释: 在这个示例中,我们将原始对象obj1克隆到对象obj2中。由于它们都内部引用同一内存地址,如果改变obj2的id,也会改变obj1的id。
obj2.id = 2 将改变obj1的id。
这被称为浅复制。浅复制意味着一旦我们对克隆对象进行更改,原始对象也会反映这些更改。
但是,在深复制的情况下,克隆对象的值的更改不会反映到原始对象中,因为它们指向不同的引用对象。原始对象有自己的引用对象,克隆后的对象也有自己的引用对象。它们是不同的。
如何避免浅复制,以使对克隆对象的更改不影响我们的原始对象。我们可以使用以下方法来避免浅复制。
- 使用展开运算符
- 使用Object.assign运算符
- 使用JSON.stringify和JSON.parse
使用展开运算符: 我们可以通过使用展开运算符来避免创建浅复制。
Javascript
<script>
var obj1 = {
id: 1,
company: "GFG"
};
var obj2 = { ...obj1 };
obj2.id = 2;
console.log(obj1.id);
console.log(obj2.id);
</script>
输出:
1
2
这里我们用对象 obj2 更改 id,但是它没有改变对象 obj1 的 id。
使用 Object.assign 操作符: 它需要两个参数:
- 空对象和
- 原始对象
Javascript
<script>
var obj1 = {
id: 1,
company: "GFG"
};
var obj2 = Object.assign({}, obj1);
obj2.id = 2;
console.log(obj1.id);
console.log(obj2.id);
</script>
输出:
1
2
但是使用Object.assign运算符的问题在于,对于嵌套对象的情况它并不能完美地工作。
JavaScript
<script>
var obj1 = {
id: 1,
company: "GFG",
details:
{
employee_no: 10
}
};
var obj2 = Object.assign({}, obj1);
obj2.details.employee_no = 20;
console.log(obj1.details.employee_no);
console.log(obj2.details.employee_no);
</script>
输出:
20
20
在这种情况下,我们有一个嵌套的对象,并且我们正在使用obj2的帮助改变employee_no。由于这个原因,obj1的employee_no也被改变了。因此,在嵌套对象的情况下,Object.assign并不完全有效。
JSON.stringify和JSON.parse: 在嵌套对象的情况下,它的工作效果非常好。与Object.assign操作符不同,当我们对克隆对象进行任何更改时,它不会改变我们的原始对象。
Javascript
<script>
var obj1 = {
id: 1,
company: "GFG",
details:
{
employee_no: 10
}
};
var obj2 = JSON.parse(JSON.stringify(obj1))
obj2.details.employee_no = 20;
console.log(obj1.details.employee_no);
console.log(obj2.details.employee_no);
</script>
输出:
10
20
极客教程