js浅拷贝和深拷贝以及注意事项

简介:js浅拷贝原理,深拷贝原理,深拷贝与浅拷贝的区别,structuredClone实现深拷贝

JavaScript有两种数据类型,基础数据类型和引用数据类型。基础数据类型都是按值访问的,我们可以直接操作保存在变量中的实际的值。而引用类型如Array,我们不能直接操作对象的堆内存空间。引用类型的值都是按引用访问的,即保存在变量对象中的是一个地址,该地址与堆内存的实际值相关联

1. 浅拷贝原理

浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用(地址),所以改变新对象,旧对象也会改变,因为新旧对象共享一块内存。浅拷贝的方法实现代码如下:

Object.assign(目标, 源数据)

注意:当对象只有一级属性为深拷贝,当对象中有多级属性时,二级属性后就是浅拷贝

下面的案例中我们使用Object.assign进行拷贝时会有意向不到怪想:

var obj = {
    id: 1,
    name: 'andy',
    msg: {
        age: 18
    }
};

var copy1 = {};
Object.assign(copy1, obj);
console.log(copy1)

上面我们已经通过Object.assign将obj拷贝到copy1中,现在我们对copy1的name值进行修改:

copy1.name = '测试';
console.log(copy1,obj) 
//打印结果:
// { "id": 1, "name": "测试", "msg": { "age": 18 } }
// {"id": 1,"name": "andy","msg": {"age": 18}}

从打印结果来看,修改copy1的name属性后没有改变原对象的值,这不就变成是深拷贝。但是如果我们对二级属性msg.age进行修改:

copy1.msg.age = 1111;
console.log(copy1,obj) 
//打印结果:
// { "id": 1, "name": "测试", "msg": { "age": 1111 } } 
// {"id": 1,"name": "andy","msg": {"age": 1111}}

从打印结果可以看出,二级属性被修改后原对象的二级属性也被修改了,这时Object.assign就变成了浅拷贝

2. 深拷贝原理

复制并创建一个一模一样的对象,不共享内存,修改新对象,旧对象保持不变。

对于深拷贝最快的实现方式就是通过JSON类将对象转成json字符串再反转成新的对象,具体代码如下:

let new_obj = JSON.parse(JSON.stringify('待复制的对象'));

3. 深拷贝与浅拷贝的区别

浅拷贝:只复制指向某个对象的指针,而不复制对象本身,新旧对象共享一块内存。

深拷贝:复制并创建一个一模一样的对象,不共享内存,修改新对象,旧对象保持不变。

4. structuredClone实现深拷贝

structuredClone 是一个新的深度拷贝方法,使用起来简单,结果也是同步返回

var obj_copy = structuredClone(obj)

注意:它的兼容性还不太理想,使用时需要先测试一下网站支持的浏览器版本是否足够

 

有遗漏或者不对的可以在我的公众号留言哦

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1