深拷贝 与 浅拷贝

深拷贝 与 浅拷贝

  • 深拷贝 与 浅拷贝 的概念
  • 浅拷贝的几种方式
  • 深拷贝的几种方式

1:深拷贝 与 浅拷贝 的概念

  • 浅拷贝
    所谓浅拷贝就是在对象复制时,只是对对象中的数据成员进行简单的赋值,(复制一个对象的内存地址)而不是复制对象本身。新旧对象共享同一块内存地址。
  • 深拷贝
    所谓深拷贝就是完全是一份新的地址,旧对象所拥有的属性和值完全复制一份到新的地址,换句话说,修改一个对象不会影响另外一个对象。

2:浅拷贝的几种方式

  • 直接赋值
const obj = {name : 'minmin',age: 18};
const obj2 = obj;
obj2.name = 'keke';
console.log(obj); // { name: 'keke', age: 18 }
  • Object.assign 方法
    可以把任意对象合并到前面第一个对象里面。
const obj = { name: 'minmin' };
Object.assign(obj, { age: 18 }, { gender: 'male' }, { age: 19 });
console.log(obj); // { name: 'minmin', age: 19, gender: 'male' }

Object.assign 方法也是一个浅拷贝。例如:

const obj = {
    name: 'minmin', 
    friend: {
        name: 'keke',
        age: 18
    }
};
const obj2 = {};
Object.assign(obj2,obj); // 也是一个浅拷贝
obj2.friend.name = 'nannan';
console.log(obj);

但是 Object.assign 拷贝的对象属性值对应的是普通数据类型,没有对象的话,就是一个深拷贝

const obj = {
  name: 'minmin', 
  friend: 'keke'
};
const obj2 = {};
Object.assign(obj2,obj); // 深拷贝
obj2.name = 'nannan';
console.log(obj);
  • ES6 的扩展运算符
const obj = {
    name: 'minmin', 
    friend: {
        name: 'keke',
        age: 18
    }
 };
const obj2 = {...obj};
obj2.friend.name = "nannan";
console.log(obj); // { name: 'minmin', friend: { name: 'nannan', age: 18 } }

同样,如果只有一层的话,那就是一个深拷贝

const obj = {
    name: 'minmin', 
    friend: "keke"
};
const obj2 = {...obj};
obj2.name = "nannan";
console.log(obj); // { name: 'minmin', friend: 'keke' }
  • 数组的 concat 方法
const arr = [1,2,{name : 'minmin'}];
const arr2 = arr.concat();
arr2[2].name = 'keke';
console.log(arr);
  • jQuery 中提供了深浅拷贝的方法
    在 jQuery 中,提供了 $.extend(deep,target,object1,objectN)

    deep:布尔值,true 代表深拷贝,false 代表浅拷贝;
    target:要拷贝的目标对象;
    object1:待拷贝到第一个对象的对象;
    objectN:待拷贝到第N个对象的对象;
    
<body>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
        const obj = {
            name : 'minmin',
            age : 18,
            friend : {
                name : 'keke'
            }
        }
        const obj2 = {};
        $.extend(obj2,obj);
        obj2.friend.name = 'nannan';
        console.log(obj);
    </script>
</body>

3:深拷贝的几种方式

  • jQuery 中的 $.extend 方法x
<body>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
        const obj = {
            name : 'minmin',
            age : 18,
            friend : {
                name : 'keke'
            }
        }
        const obj2 = {};
        $.extend(true,obj2,obj);
        obj2.friend.name = 'nannan';
        console.log(obj);
    </script>
</body>
  • JSON.parse(JSON.stringify())
const obj = {
    name : 'minmin',
    friend : {
        name : 'keke'
    }
}
const obj2 = JSON.parse(JSON.stringify(obj));
obj2.friend.name = 'nannan';
console.log(obj);

上面使用的方式是JSON的方法,但是JSON和js对象还是有区别的。区别在于 JSON 表示的是数据,键所对应的值不能是函数。

但是,这种深拷贝方式有一个缺陷,如果我拷贝的对象有方法,方法不能够被拷贝。

const obj = {
    name : 'minmin',
    friend : {
        name : 'keke'
    },
    sayHello : function(){},
    gender : 'male'
}
const obj2 = JSON.parse(JSON.stringify(obj));
console.log(obj2); // { name: 'minmin', friend: { name: 'keke' }, gender: 'male' }
  • 手写递归方法来实现深拷贝
const obj = {
    name: 'minmin',
    friend: {
        name: 'keke'
    },
    sayHello: function () { },
    gender: 'male'
}
function deepCopy(oldObj, newObj) {
    for (let key in oldObj) {
        let item = oldObj[key];
        if (item instanceof Array) {
            newObj[key] = {};
            deepCopy(item, newObj[key]);
        }
        else if (item instanceof Object) {
            if (item instanceof Function) {
                newObj[key] = oldObj[key];
            } else {
                newObj[key] = {};
                deepCopy(item, newObj[key]);
            }
        }
        else {
            newObj[key] = item;
        }

    }
}
const cloneObj = {};
deepCopy(obj, cloneObj);
cloneObj.friend.name = 'nannan';
console.log(obj);
console.log(cloneObj);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值