JavaScript - 深浅拷贝Object.assign()

2020-03-17  本文已影响0人  小棋子js

引入:值类型存储在栈内存中,引用类型存储在堆内存,深浅拷贝主要是针对引用类型来说的(数组、对象等)。(值类型直接赋值就能开辟新存储空间,引用类型直接赋值得到的是引用,实际还是同一个空间)

一.浅拷贝:复制的只是引用,原对象属性的改变会引起拷贝对象对应引用属性的变化。

方法1:遍历并复制(只能拷贝第一层)

function simpleCopy(obj){
    const targetObj = Object.prototype.toString.call(obj) == '[object Array]'?[]:{};
    for(let key in obj){
        targetObj[key] = obj[key];
    }
    return targetObj;
}
let a = {
    name:'tom',
    age:20,
    friends:{
        student:['jack']
    }
}
let b = simpleCopy(a);
a.friends.student = ['tony'];
console.log(a);// { name: 'tom', age: 20, friends: { student: [ 'tony' ] } }
console.log(b);// { name: 'tom', age: 20, friends: { student: [ 'tony' ] } }

方法2.使用Object.assign()(只能拷贝第一层)

let a = {
    name:'tom',
    age:20,
    friends:{
        student:['jack']
    }
}
let b = Object.assign({},a);
a.friends.student = ['tony'];
console.log(a);// { name: 'tom', age: 20, friends: { student: [ 'tony' ] } }
console.log(b);// { name: 'tom', age: 20, friends: { student: [ 'tony' ] } }

二.深拷贝:开辟新的内存空间,原对象与拷贝对象之间没有影响。

方法1:使用JSON.parse()加JSON.stringify()

let obj = {
  name:'tom',
  age:10,
  friend:{
    name:'jack'
  }
};
let copy = JSON.parse(JSON.stringify(obj));
obj.name = 'elric';
console.log(obj);// {name: "elric", age: 10, friend: {…}}
console.log(copy);// {name: "tom", age: 10, friend: {…}}

copy对象的name没有因为obj的name变化而变化,说明该方法实现了深拷贝。缺陷:无法拷贝函数、undefined

方法2:递归层层拷贝,直到基本值类型为止。

function deepCopy(obj){
    // 判断是否为引用类型
    if(!obj && typeof obj !== 'object'){
        throw new Error('type error');
    }
    const targetObj = Object.prototype.toString.call(obj) == '[object Array]'?[]:{};
    for(let key in obj){
        let prop = obj[key]; // 避免相互引用造成死循环,如obj.a=obj
        if (prop == obj) {
          continue;
        }
        // 只有对象本身的属性才复制
        if(obj.hasOwnProperty(key)){
            // 如果是引用类型继续向下
            if(obj[key] && typeof obj[key] == 'object'){
                targetObj[key] = deepCopy(obj[key]);
            }else{
                targetObj[key] = obj[key];
            }
        }
    }
    return targetObj;
}
let a = {
    name:'tom',
    age:undefined,
    friends:['tom','jack','merry'],
    sayName(){
        console.log(this.name);
    }
}
let b = deepCopy(a);
a.age = 20;
a.name = 'tony';
console.log(a);
console.log(b);
b.sayName();
上一篇 下一篇

猜你喜欢

热点阅读