JavaScript中的浅拷贝和深拷贝

在JavaScript中,拷贝对象或数组时,我们经常会遇到浅拷贝(shallow copy)和深拷贝(deep copy)的概念。理解这两者之间的区别对于避免潜在的bug至关重要。

图片[1]_JavaScript中的浅拷贝和深拷贝_知途无界

浅拷贝(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 }]

在这个例子中,shallowCopyArrayoriginalArray的一个浅拷贝。当我们修改shallowCopyArray中对象的属性时,由于这个对象是被引用的,所以originalArray中的对应对象也会受到影响。

深拷贝(Deep Copy)

深拷贝是指创建一个新对象或数组,并且递归地复制原对象或数组中的所有元素,包括嵌套的对象和数组。这样,新对象或数组与原对象或数组完全独立,修改新对象或数组不会影响原对象或数组。

示例

要实现深拷贝,我们可以使用JSON的序列化和反序列化(但这种方法有局限性,比如不能处理函数、undefinedNaNInfinity等特殊值),或者使用递归函数,或者使用第三方库如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
喜欢就点个赞,支持一下吧!
点赞41 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容