浅拷贝和深拷贝

117 阅读1分钟

浅拷贝

let arr = [
    {
        name: 'lilei',
        age: 18
    },
    {
        name: 'hanmeimei',
        age: 19
    }
]

//五种实现浅拷贝的方法
let aCope = Object.assign([], arr)
let aCope = [...arr]
let aCope = Object.fromEntries(Object.entries(arr))
let aCope = Object.create({}, Object.getOwnPropertyDescriptors(arr))
let aCope = Object.defineProperties({}, Object.getOwnPropertyDescriptors(arr))

浅拷贝原理

for (let key of Object.keys(arr)) {
    aCope[key] = arr[key]
}

深拷贝

常用的简单方法

let depCope = JSON.parse(JSON.stringify(object))

弊端

1、如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;
2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;
3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
6、如果对象中存在循环引用的情况也无法正确实现深拷贝;

简单完善的深拷贝方法

let obj = {
    name : 'xuxiu',
    arr : [1,[2,3],4],
};
let depCloneObj=deepClone(obj)
depCloneObj.name = "faker";
depCloneObj.arr[1] = [5,6]; 
function deepClone(obj) {
    if (obj === null) return obj; 
    if (obj instanceof Date) return new Date(obj);
    if (obj instanceof RegExp) return new RegExp(obj);
    if (typeof obj !== "object") return obj;
    let cloneObj = new obj.constructor();
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        // 递归
        cloneObj[key] = deepClone(obj[key]);
      }
    }
    return cloneObj;
}

console.log('obj',obj) // obj { name: 'xuxiu', arr: [ 1, [ 2, 3 ], 4 ] }
console.log('depCloneObj',depCloneObj) // depCloneObj { name: 'faker', arr: [ 1, [ 5, 6], 4 ] }