由于对象的赋址存储,导致日常业务中,如果把一个对象赋值给了另外一个,那么其中一个的更改会导致另外一个也变了。
所以对象的深拷贝就需要去从中打断两者之间的关联,通过深层次的循环递归将取址类的数据的值逐个转移到新对象的同名属性中。
日常的assgin,concat.sclie以及循环赋值等,只能拿来做浅拷贝,也就是一维对象。
说到深拷贝,json.parse(json.stringfy)十个伪深拷贝,存在很多缺陷,但其实日常业务中也基本能用,不会出现差错,但终归还是不够严谨。
json.parse(json.stringfy)的缺陷问题,在挺早的一篇博客中就有讲过,这里就不再重复。
昨日看了一篇关于js面向对象概念以及原型,原型链的文章,感觉对深拷贝有了新的理解。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
</html>
<script type="text/javascript">
var obj1 = {
a:{
name:'李雷',
age:'30',
ab:[1,2,{
name:'李小雷',
age:'6'
}]
},
b:[1,2,[4,5,6]],
c:function(){
console.log('1234')
},
d:'sdadasda',
e:10086,
f:[{
name:'陈大雷',
age:'18'
},{
name:'王大明',
age:'18',
child:[{
name:'王小明明',
age:'10',
arr:[1,2,3]
}]
}],
g:undefined,
h:null
}
function deep(data){
const result = Array.isArray(data)?[]:{};
for(let i in data){
if(data.hasOwnProperty(i)){//排除原型链,_proto_延伸至构造函数的prototype
//这里虽然只是一个普通的对象,或者说它的_proto指向的是Object.prototype,倒也无大碍。
//类型的判断可以用 instance typeof Array.isArray constructor等
if(data[i] && typeof data[i] === 'object'){
result[i] = deep(data[i])
}else{
result[i] = data[i]
}
}
}
return result
}
let hx = deep(obj1)
console.log(hx)
</script>