JS—深拷贝和浅拷贝

31 阅读2分钟

浅拷贝

定义:浅拷贝对基本类型是值拷贝,对引用数据类型是地址拷贝。基本类型包括字符串、数字、布尔值等。

//基本数据类型
var a=1;
var b=a;          //浅拷贝
b=2;              //改变b的值,并不会影响到a,因为浅拷贝对基本类型而言就是值拷贝
console.log(a);   //1

//引用数据类型(对象类型)
var a={
    name : "aaa"
}
var b = a;
b.name = 'bbb';   //改变b的值,会影响到a,因为浅拷贝对引用数据类型而言只是地址拷贝                  
console.log(a);   //{ name: 'bbb' }

对基本数据类型浅拷贝时,a打印出来还是1,b并没有影响到a

对引用数据类型浅拷贝时,b保存的是和a一样的地址,所以a的属性值被改变了

深拷贝

定义:深拷贝是指除了拷贝基本类型的值,还完全复刻了引用数据类型。

一个对象在内存中是固定存在的,如果要对其进行深拷贝,唯一的办法就是创建一个新的对象,里面的值完全复刻原来的对象。

//引用数据类型(对象类型)
var a = {
    name : "aaa"
}
var b = {
    name : a.name
}
b.name = 'bbb'    //此时对b进行操作,不会影响到a,即深拷贝
console.log(a);   //{ name: 'aaa' }
console.log(b);   //{ name: 'bbb' }

实现深拷贝

方法一:Object.assign( )——通过复制一个或多个对象来创建一个新的对象

//Object.assign( )实现深拷贝
//如果属性值是简单类型,则是 深拷贝对象
//(深拷贝对象 其地址是独立的,得到的是一个全新的对象。当一个值改变,并不会影响到另一个值)
var a = {
    name : "aaa"
}
var b = {}
Object.assign(b,a);
console.log(b);  //{ name: 'aaa' }

Object.assign(b,a);
a.name = "bbb"   //当改变a的值,b的值不会改变,即深拷贝对象
console.log(b);  //{ name: 'aaa' }

//如果属性值是对象类型,则得到的新对象为 浅拷贝对象
//(浅拷贝对象 其地址是共享的,拷贝的是地址。当一个值改变,另一个值也会跟着改变)
var a = {
    name : "aaa",
    prop : {
        name : "aaa1",
        prop : "prop"
    }
}
var b = {}
Object.assign(b,a.prop);
console.log(b);  //{ name: 'aaa1', prop: 'prop' }

Object.assign(b,a);
console.log(b);  //{ name: 'aaa', prop: { name: 'aaa1', prop: 'prop' } }

Object.assign(b,a);
a.prop.name = "bbb"   //当改变a的值,b的值也会改变,即浅拷贝对象,只是地址拷贝而已
console.log(b);  //{ name: 'aaa', prop: { name: 'bbb', prop: 'prop' } }

小结:

1、进行拷贝时,基本类型改变的是内容,引用类型改变的是地址。

2、对于Object.assign( )方法,如果属性值是简单类型,是深拷贝对象;如果属性值是对象或其他引用数据类型,得到的新对象为浅拷贝对象。