理解深拷贝和浅拷贝的方法

177 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」]

前言

所谓深浅拷贝,都是进行复制,那么区别主要在于复制出来的新对象和原来的对象是否会互相影响,改一个,另一个也会变。

什么是深浅拷贝?

浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精准拷贝,如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另外一个对象。

深拷贝是将一个对象从对内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,切修改新的对象不会影响原对象。

看一下两个拷贝方法

var a = {name:'张三'}
var a1 = shallowCopy(a) //浅拷贝方法
a1.name === a.name //true 新对象和旧对象是共享的同一个内存

var a2 = deepCopy(a) //深拷贝方法
a2.name === a.name  //false  新对象和旧对象不共享一个内存

两个拷贝的区别

这两个的主要区别就是,复制的是引用(地址)还是复制的是实例

浅拷贝方法

var obj1 = {
    'name' : '张三',
    'age' :  '18',
    'language' : [1,[2,3],[4,5]],  //Array
};
 var obj3 = shallowCopy(obj1);
 obj3.name = "李四";
 obj3.language[1] = ["6","7"];
 function shallowCopy(src) {
    var dst = {};
    for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
            dst[prop] = src[prop];
        }
    }
    return dst;
}
console.log('obj1',obj1)
console.log('obj3',obj3)

image.png

深拷贝方法

var obj1 = {
    'name' : '张三',
    'age' :  '18',
    'language' : [1,[2,3],[4,5]],  //Array
};
 var obj3 = deepCopy(obj1);
 obj3.name = "李四";
 obj3.language[1] = ["6","7"];
function deepCopy( source ) {
if (!isObject(source)) return source; //如果不是对象的话直接返回
    let target = Array.isArray( source ) ? [] : {} //数组兼容
    for ( var k in source ) {
    	if (source.hasOwnProperty(k)) {
    		if ( typeof source[ k ] === 'object' ) {
            	target[ k ] = deepCopy( source[ k ] )
        	} else {
            	target[ k ] = source[ k ]
        	}
    	}
    }
    return target
}

function isObject(obj) {
    return typeof obj === 'object' && obj !== null
}
console.log('obj1',obj1)
console.log('obj3',obj3)

image.png

总结

浅拷贝只是对指针的拷贝,拷贝后两个指针指向的是同一个内存地址,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同内存地址的指针。