深克隆与浅克隆的区别
浅克隆不仅赋值了数据,还赋值了地址,操作数据会改变原有数据
深克隆赋值了数据,但内存地址不同,不会影响原有数据
定义一个obj 分别看看深浅克隆的效果
let obj = {
a:100,
b:[10,20,30],
c:{
x:2
},
d:/^\d+$/,
e:function(){
console.log('1')
},
f:new Date()
}
浅克隆
let obj2 = {}
for(let key in obj){
if(obj.hasOwnProperty(key)){
obj2[key] = obj[key]
}
}
console.log(obj)
console.log(obj2)
浅克隆有什么弊端?
当修改了obj2的数据时,obj的数据也跟着改变了,数据发生改变会造成视图重新渲染,所以需要用到深克隆
深克隆
1.先将对象转换成json字符串再转换成对象
let obj2 = JSON.parse(JSON.stringify(obj))
console.log(obj)
console.log(obj2)
当修改obj2数据时,obj的数据并不会发生改变,深克隆成功了,但是这种方法有一个弊端
1.obj2.d中的正则表达式为空
2.obj2.e 函数没有克隆
3.obj.f date转换成了字符串
所以这种方法当数据中有正则表达式,函数,date时不能使用
2.定义一个函数来完成深克隆并过滤特殊数据
function deepClone(obj){
//过滤特殊数据
if(obj === null) return null //typeof null === 'object'
if(typeof obj !== 'object') return obj
//正则
if(obj instanceof RegExp){
return new RegExp(obj)
}
//Date
if(obj instanceof Date){
return new Date(obj)
}
//函数
if(obj instanceof Function){
return new Function(obj)
}
//防止创建空对象,克隆数据与原数据保持相同所属类
let newObj = new obj.constructor;
for(let key in obj){
if(obj.hasOwnProperty(key)){
// newOBj[key] = obj[key] //如果obj[key]也为对象 需要再次调用函数,
newObj[key] = deepClone(obj[key]) //递归
}
}
return newObj
}
let obj2 = deepClone(obj)
console.log(obj)
console.log(obj2)
可以看到 obj2 与 obj 数据一致 正则 函数 date正常
修改obj2数据不影响obj数据