浅拷贝
什么是浅拷贝
只拷贝基本数据类型,而对象引用的对象依然指向原来的对象。因此如果修改引用数据类型中的数据,会修改到原对象。
代码实现
function shallowCopy(obj){
//首先判断传入的数据是否为对象或者数组
if(typeof obj !== 'object')return
//根据传入的是数组还是对象新建空[]||{}
let newObj = Array.isArray(obj)?[]:{}
for(let i in obj){
if(obj.hasOwnProperty(i)){
newObj[i] = obj[i];
}
}
return newObj
}
let arr = [1,2,3,[1,2,3]];
let newArr = shallowCopy(arr);
newArr[3][1] = 33;
console.log(arr)//[1,2,3,[1,33,3]]
console.log(newArr)//[1,2,3,[1,33,3]]
浅拷贝的其他方式
- Object.assign()
- xxx.slice()
- xxx.concat()
深拷贝
什么是深拷贝
不仅复制对象的基本数据类型,对象中引用的对象也复制。会生成一个全新的对象,修改这个对象不会影响到原来的对象。
深拷贝的代码实现
//深拷贝
function deepCopy(obj){
if(typeof obj !== 'object')return
let newObj = Array.isArray(obj)?[]:{};
for(let i in obj){
if(obj.hasOwnProperty(i)){
newObj[i] = typeof(obj[i]) == 'object'?deepCopy(obj[i]):obj[i];
}
}
return newObj
}
let arr = [1,2,3,[1,2,3]];
let newArr = deepCopy(arr);
newArr[3][1] = 33;
console.log(arr)//[1,2,3,[1,2,3]]
console.log(newArr)//[1,2,3,[1,33,3]]
深拷贝的其他实现方式
- 先转化为json字符串再转化为对象,JSON.parse(JSON.stringfy(xxx))
- 函数库lodash的CloneDeep
使用JSON进行深拷贝的话会有哪些数据拷贝不到
- 如果obj中存在时间对象,经过深拷贝会变成字符串
- 如果obj中有RegExp正则或者Error对象,只能得到空对象
- 如果obj中有函数,undefined,序列化后会将函数和undefined丢失
- 如果obj中有NAN,Infinity,-Infinity序列化后的结果会变成null
- 只能序列化对象的可枚举自身属性,如果obj中的对象是构造函数生成的,则使用JSON进行深拷贝以后会丢失对象的constructor。
- 如果对象中存在循环引用也无法进行深拷贝。
- 解决方法:使用lodash库中的深拷贝。
场景
-增删改查,修改数据的时候。