Home

在 JavaScript 中的深浅拷贝

# 浅拷贝

我们先来看下数组拷贝的常见方法, slice() concat() ...

var arr = [1, 2, 3, 4, 5];
var arr1 = arr.concat();
var arr2 = arr.slice();
var arr3 = [...arr]
console.log(arr1); //[1, 2, 3, 4, 5]
console.log(arr2); //[1, 2, 3, 4, 5]
console.log(arr3); //[1, 2, 3, 4, 5]

都是返回了一个新数组,不改变原来的数组, 但都是浅拷贝。如果数组里有对象,那么不会拷贝对象的值,而是拷贝对象的引用。

assign() 对象的拷贝 也是浅拷贝

var obj = {
    name: "ninja",
    address: {city: "shanghai"}
}
var obj1 = Object.assign({},obj);
var obj2 = {...obj};
obj.address.city = "beijing";
console.log(obj1); //{name: "ninja", address:{city: "beijing"}
console.log(obj2); //{name: "ninja", address:{city: "beijing"}

# 利用JSON.stringify实现对数组和对象的深拷贝

var arr = [1, 2, 3, 4, { value: 5 }];
var arr1 = JSON.parse(JSON.stringify(arr));
arr[4].value = 6;
console.log(arr1); //[1, 2, 3, 4, { value: 5 }]

var obj = {
    name: "ninja",
    address: {city: "shanghai"}
}
var obj1 = JSON.parse(JSON.stringify(obj));
obj.address.city = "beijing";
console.log(obj1); //{name: "ninja", address:{city: "shanghai"}

该方法不能对undefined symbol function 进行拷贝

# 利用递归实现数组和对象深拷贝

function deepCopy(obj) {
    if (typeof obj !== 'object') return;
    var newObj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return newObj;

}

使用

var arr = [1, 2, 3, 4, { value: 5 }];
var arr2 = deepCopy(arr);
arr[4].value = 6;
console.log(arr);//1, 2, 3, 4, { value: 6 }]
console.log(arr2);//1, 2, 3, 4, { value: 5 }]

去掉递归就是浅拷贝

function shallowCopy(obj) {
    if (typeof obj !== 'object') return;
    var newObj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}

验证一下

var arr = [1, 2, 3, 4, { value: 5 }];
var arr2 = shallowCopy(arr);
arr[4].value = 6;
console.log(arr);//1, 2, 3, 4, { value: 6 }]
console.log(arr2);//1, 2, 3, 4, { value: 6 }]