JS中对象深拷贝的几种方法
既然看到了这里,想必已经知道什么是深拷贝以及它的作用,这里不再赘述概念1、递归
有算法基础都可以写出来、简单易懂;可以拷贝所有成员属性和方法,推荐使用
//核心代码
function deepCopy(raw) {
let obj = {}
for (const k in raw) {
if (raw.hasOwnProperty(k)) {
const type = typeof raw[k]
switch (type) {
case "object":
obj[k] = deepCopy(raw[k])
break
case "function":
obj[k] = function () {
return raw[k].call(obj, ...arguments)
}
break
default:
obj[k] = raw[k]
}
}
}
return obj
}
//测试一下拷贝后的属性、对象、函数是否正常
let obj = {
name: "张三",
getName() {
console.log(this.name)
},
relation: {
friend: "李四",
say(a) {
console.log(this.friend + a)
}
}
}
let deepO = deepCopy(obj)//拷贝obj
/*检验第一层属性及方法*/
deepO.name = "胡汉三"
console.log(obj.name) //依然是`张三`,测试通过
deepO.getName()//`胡汉三`,测试通过
/*检验深层次属性及方法*/
deepO.relation.friend = "王大爷"
console.log(obj.relation.friend) //依然是`李四`,测试通过
deepO.relation.say(",你好")//`王大爷,你好`,测试通过
2、 JSON对象拷贝
缺点:无法拷贝函数
let deepO = JSON.parse(JSON.stringify(obj))//拷贝obj
/*检验第一层属性及方法*/
deepO.name = "胡汉三"
console.log(obj.name) //依然是`张三`,测试通过
deepO.getName()//error
/*
检验深层次属性及方法
*/
deepO.relation.friend = "王大爷"
console.log(obj.relation.friend) //也变成了 `王大爷`,结果不符合预期
deepO.relation.say(",你好")//error
3、 Object.assign({ },obj)
实际上这是一个浅拷贝函数,可以拷贝所有成员属性和方法
let deepO = Object.assign({},obj)//拷贝obj
/*检验第一层属性及方法*/
deepO.name = "胡汉三"
console.log(obj.name) //依然是`张三`,测试通过
deepO.getName()//`胡汉三`,测试通过
/*
检验深层次属性及方法
===不符合预期===
*/
deepO.relation.friend = "王大爷"
console.log(obj.relation.friend) //也变成了 `王大爷`,结果不符合预期
deepO.relation.say(",你好")//`王大爷,你好`,结果不符合预期
所以方案最好的应该是第一种,如果不需要拷贝函数使用第二种,第三中只适合一层对象,大家可以根据需求使用哦