JS的深浅拷贝

139 阅读1分钟

JS中的引用数据类型(对象和数组)有深浅拷贝两种方式

浅拷贝:与原对象共用同一内存,修改会使原对象也修改。

浅拷贝主要用ES6的Object.assign()方法实现

let obj1 = {name:'张三',age:'18'}
let obj2 = Object.assign(obj1);
obj1.name = '李四';
console.log(obj1) //{name:'李四',age:'18'}
console.log(obj2) //{name:'李四',age:'18'}

深拷贝:开辟一块新内存,将原对象的所有值复制过去,修改不会改变原对象的数据。

1、JSON的parse和stringify,缺点是对象中属性值为undefined,函数和symbol的属性会省略。

let obj1 = {
    name: '张三',
    age: undefined,
    see: function(){
       console.log("看");
    },
    son: {
       name: '张四'
    }
}
let obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj2) /* {name: '张三', son: {name: '张四'}}*/
obj1.name='李四'
console.log(obj2) /* {name: '张三', son: {name: '张四'}}*/

2、用Object.assgin({},源对象)来实现,缺点是只能复制基本数据类型(即一层),如果对象属性有属性值是引用数据类型(多层)的会相当于浅拷贝。

let obj1 = {
    name: '张三',
    score: [1,2,3,4,5]
}
let obj2 = Object.assign({}, obj1);
obj1.name = '李四';
console.log(obj2.name)  //张三
obj1.score.push(6)
console.log(obj2.score)  // [1,2,3,4,5,6]

3、自定义函数递归层层遍历

function deepClone(target){
    if(target === null) return target;
    if(typeof target !== 'object') return target;
    const cloneTarget =  Array.isArray(target) ? [] : {};
    for(let prop in target){
        if(target.getOwnProperty(prop)){
            cloneTarget[prop] = deepClone(target[prop])
        }
    }
    return cloneTarget;
}