一.直接复制对象问题
const obj={
uname:'pink',
age:18
};
const o=obj;
console.log(o);
o.age=20;
console.log(o);
console.log(obj);
利用o来复制obj对象,改变o对象里面的属性值,obj里面的属性值也会发生改变
二.浅拷贝
首先浅拷贝和深拷贝只针对引用类型
浅拷贝:拷贝的是地址
常见方法:
1.拷贝对象:Object.assgin()/展开运算符{...obj}拷贝对象
2.拷贝数组:Array.prototype.concat()或者〔[...arr]
const obj={
uname:'pink',
age:18,
family:{
baby:'小pink'
}
}
const o={}
Object.assign(o,obj);
o.age=20;
o.family.baby='老pink'
console.log(o);
console.log(obj);
如果是简单数据类型拷贝值,引用数据类型拷贝的是地址(简单理解:如果是单层对象,没问题,如果有多层就有问题)
直接复制和浅拷贝的区别
直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址
浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响
浅拷贝怎么理解?
拷贝对象之后,里面的属性值是简单数据类型直接拷贝值
如果属性值是引用数据类型则拷贝的是地址
三.深拷贝
首先浅拷贝和深拷贝只针对引用类型深拷贝:拷贝的是对象,不是地址
常见方法:
1.通过递归实现深拷贝
2.lodash/cloneDeep
3.通过JSON.stringify()实现
1.通过递归实现深拷贝
函数递归:
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
简单理解:函数内部自己调用自己,这个函数就是递归函数
递归函数的作用和循环效果类似
由于递归很容易发生“栈溢出”错误( stack overflow),所以必须要加退出条件return
const obj={
uname:'pink',
age:18,
hobby:['乒乓球','足球'],
family:{
baby:"小pink"
}
}
const o={}
// console.log(obj["uname"]);
// 拷贝函数
function deepCopy(newObj,oldObj){
for(let k in oldObj){
//处理数组问题
if(oldObj[k] instanceof Array){
//newObj[]接手[]
//oldObj[k]['乒乓','足球']
newObj[k]=[];
deepCopy(newObj[k],oldObj[k]);
}else if(oldObj[k] instanceof Object){
newObj[k]={};
deepCopy(newObj[k],oldObj[k]);
} else{
// k属性名 unmae oldObj[k]属性值 18
///newObj[k ]=== o.uname
newObj[k]=oldObj[k];
}
}
}
deepCopy(o,obj)//函数调用 两个参数 o 新对象 obj旧对象
console.log(o);
注意:先递归数组在递归对象
2.js库lodash里面cloneDeep内部实现了深拷贝
<!-- 先引用 -->
<script src="./lodash.min.js"></script>
const obj = {
uname: 'pink',
age: 18,
hobby: ['乒乓球', '足球'],
family: {
baby: "小pink"
}
}
const o= _.cloneDeep(obj);
console.log(o);
o.family.baby="老pink";
console.log(obj);
3.通过JSON.stringify()实现
const obj = {
uname: 'pink',
age: 18,
hobby: ['乒乓球', '足球'],
family: {
baby: "小pink"
}
}
// 把对象转换未JSON字符串
// console.log( JSON.stringify(obj) );
// 把字符串转换成对象
const o= JSON.parse(JSON.stringify(obj))
console.log(o);
o.family.baby="123";
console.log(obj);