浅拷贝: 创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
深拷贝: 将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
浅拷贝的实现方式:
Object.assign() 方法: 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
Array.prototype.slice():slice() 方法返回一个新的数组对象,这一对象是一个由 begin和end(不包括end)决定的原数组的浅拷贝。原始数组不会被改变。
拓展运算符`…`:[...arr]
深拷贝的实现方式:
乞丐版: JSON.parse(JSON.stringify(object)),缺点诸多(会忽略undefined、symbol、函数;不能解决循环引用;不能处理正则、new Date())
基础版(面试够用): 浅拷贝+递归 (只考虑了普通的 object和 array两种数据类型)
1 function cloneDeep(target,map = new WeakMap()) { 2 if(typeOf taret ==='object'){ 3 let cloneTarget = Array.isArray(target) ? [] : {}; 4 5 if(map.get(target)) { 6 return target; 7 } 8 map.set(target, cloneTarget); 9 for(const key in target){ 10 cloneTarget[key] = cloneDeep(target[key], map); 11 } 12 return cloneTarget 13 }else{ 14 return target 15 } 16 17 }
1 var deepCopy = function(obj) { 2 if (typeof obj !== 'object') return; 3 var newObj = obj instanceof Array ? [] : {}; 4 for (var key in obj) { 5 if (obj.hasOwnProperty(key)) { 6 newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; 7 } 8 } 9 return newObj; 10 } 11 var b4 = deepCopy(a);