引言
由于引用类型地址引用的问题,当我们赋予某个变量一个引用类型的值然后再去使用该变量时,我们可能要特别注意会不会出现某些问题。此时我们可以借助浅拷贝或者深拷贝来解决这些问题。在面试的小伙伴可能也遇到过问关于对象的浅拷贝和深拷贝,下面就由我来带你轻松掌握关于它。
关于值类型和引用类型的赋值
如果对基本数据类型和引用数据类型的地址问题很了解的小伙伴,可以跳过该章节,如果不是很了,解推荐看看该章节,因为它能帮助你更好的理解浅拷贝和深拷贝。
基本值类型的赋值
let a=1
let b=a
b=2
流程图解:a=1
后系统创建栈地址a
,b=a
后系统创建栈地址b
,b=2
后系统重新创建栈地址b
引用值类型的赋值
const obj={a:1,b:2}
const obj1=obj
obj1.a=2
console.log(obj) // {a:2,b:2}
流程图解: obj={a:1,b:2}
后系统创建一个堆地址,然后obj
对其进行引用,const obj1=obj
后obj1
也对这个堆地址进行引用,obj1.a=2
后这个堆地址中的属性a
被修改为了2
。当我们console.log(obj)
时,我们打印的是那个地址中的内容。
浅拷贝和深拷贝
下面是一个深层次对象,因为浅拷贝和深拷贝只是针对深层次对象而言的。
const user={
name:"nb",
age:18,
sister:{
name:"hp",
age:20
}
}
对象图解:
浅拷贝
浅拷贝就是,只重新创建某对象的最外层的堆地址,内层的地址继续复用。
const obj={...user} // 浅拷贝方法一
const obj=Object.assign({},user) // 浅拷贝方法二
深拷贝
深拷贝就是,把对象的每一层都重新创建一个新的堆地址。
方法一:
优点:操作简单;可以把原型也拷贝。
缺点:当对象的属性存在函数、正则、日期对象
时,会出现问题。
const objstr=JSON.stringify(user)
const newUser=JSON.parse(objstr)
方法二:
优点:不会出现任何不好的影响。
缺点:操作复杂。
function deepClone(obj){
const cloneobj=Array.isArray(obj)?[]:{} // 拷贝对象就创建对象,拷贝数组就创建数组
for(const[k,v] of Object.entries(obj))
{
// 判断属性值是否为引用类型
if(Array.isArray(v) || Object.prototype.toString.call(v)==='[object Object]')
// 为引用类型时,递归进一步拷贝
cloneobj[k]=deepClone(v)
// 为基本数据类型时直接赋值到新的对象中
else cloneobj[k]=v
}
return cloneobj
}
const newUser=deepClone(user)
结尾
相信看完这篇文章的小伙伴已经对值类型和引用类型以及浅拷贝和深拷贝有了一个很好的了解。感谢你的观看,希望这篇文章能给你带来快乐。如果有小伙伴有一些问题或者疑惑,欢迎提出和分享。