JavaScript 深拷贝
浅拷贝和深拷贝的区别
首先,需要明白在赋值的时候有个传值和传址的区别。在JavaScript中,简单数据类型(null,undefined,string,number,boolean)在赋值的时候,其实是传值,而对象类型object(包括[],{},function,Date(),RegExp()等)都是传址。
对于深拷贝而言,所有的值都需要重新开辟内存空间,而不是传递内存地址。
深拷贝的实现
1. Object.assign({}, obj)
let user = {
name: '张三'
}
let userCopy = Object.assign({}, user)
缺点:只对第一级的变量是深拷贝
2. JSON.parse(JSON.stringify(obj))
优点:简单
缺点:无法拷贝正则表达式,undefined,function,null等
3. {...obj}
let user = {
name: '张三',
age: undefined
}
let userCopy = {...user}
user.name = "李四"
console.log(JSON.stringify(user))
console.log(JSON.stringify(userCopy))
// output
// {"name":"李四"}
// {"name":"张三"}
优点:简单
缺点:只是对于第一级的变量是深拷贝
4. 递归
function deepCopy(obj){
let res = (obj instanceof Array ? [] : {});
for (const [k, v] of Object.entries(obj)) {
res[k] = (typeof v == "object" ? deepCopy(v) : v);
}
return res;
}
优点:对于数组、对象、函数都可以支持,支持null,undefined
缺点:对于Date(),RegExp()无法支持,可以添加对于类型的判断以实现实际情况中的深拷贝需求