美文网首页
JavaScript - 深浅拷贝Object.assign()

JavaScript - 深浅拷贝Object.assign()

作者: 小棋子js | 来源:发表于2020-03-17 10:25 被阅读0次

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

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

    方法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();
    

    相关文章

      网友评论

          本文标题:JavaScript - 深浅拷贝Object.assign()

          本文链接:https://www.haomeiwen.com/subject/iguynctx.html