在JavaScript中,拷贝对象或数组时,我们经常会遇到浅拷贝(shallow copy)和深拷贝(deep copy)的概念。理解这两者之间的区别对于避免潜在的bug至关重要。
![图片[1]_JavaScript中的浅拷贝和深拷贝_知途无界](https://zhituwujie.com/wp-content/uploads/2024/10/d2b5ca33bd20241016095721.png)
浅拷贝(Shallow Copy)
浅拷贝是指创建一个新对象或数组,这个新对象或数组的元素是对原对象或数组中元素的引用(对于非原始类型如对象和数组)。换句话说,浅拷贝只复制了容器本身以及容器内第一层元素的引用,而没有递归复制容器内所有层级的元素。
示例
let originalArray = [1, 2, { a: 3 }];
let shallowCopyArray = originalArray.slice(); // 或者使用 [...originalArray]
shallowCopyArray[2].a = 4;
console.log(originalArray); // [1, 2, { a: 4 }]
console.log(shallowCopyArray); // [1, 2, { a: 4 }]
在这个例子中,shallowCopyArray
是originalArray
的一个浅拷贝。当我们修改shallowCopyArray
中对象的属性时,由于这个对象是被引用的,所以originalArray
中的对应对象也会受到影响。
深拷贝(Deep Copy)
深拷贝是指创建一个新对象或数组,并且递归地复制原对象或数组中的所有元素,包括嵌套的对象和数组。这样,新对象或数组与原对象或数组完全独立,修改新对象或数组不会影响原对象或数组。
示例
要实现深拷贝,我们可以使用JSON的序列化和反序列化(但这种方法有局限性,比如不能处理函数、undefined
、NaN
、Infinity
等特殊值),或者使用递归函数,或者使用第三方库如Lodash的cloneDeep
方法。
使用JSON序列化和反序列化的方法:
let originalObject = { a: 1, b: { c: 2 } };
let deepCopyObject = JSON.parse(JSON.stringify(originalObject));
deepCopyObject.b.c = 3;
console.log(originalObject); // { a: 1, b: { c: 2 } }
console.log(deepCopyObject); // { a: 1, b: { c: 3 } }
使用递归函数实现深拷贝(简化版,不考虑循环引用等情况):
function deepCopy(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
let copy = [];
for (let i = 0; i < obj.length; i++) {
copy[i] = deepCopy(obj[i]);
}
return copy;
} else {
let copy = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]);
}
}
return copy;
}
}
let original = { a: 1, b: { c: 2 } };
let copy = deepCopy(original);
copy.b.c = 3;
console.log(original); // { a: 1, b: { c: 2 } }
console.log(copy); // { a: 1, b: { c: 3 } }
总结
- 浅拷贝:只复制容器本身以及容器内第一层元素的引用。
- 深拷贝:递归地复制容器及其内部所有层级的元素,确保新容器与原容器完全独立。
选择使用浅拷贝还是深拷贝取决于你的具体需求。如果你只需要复制容器本身而不关心容器内元素的独立性,那么浅拷贝就足够了。但如果你需要确保新容器与原容器完全独立,那么你应该使用深拷贝。
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END
暂无评论内容