这篇文章和大家说一下js中对象引用的相关知识点。废话不多说,直接上示例。
let a = 5;
let b = a;
b += 3;
alert(a);
alert(b);
弹窗打印出来的值,分为别5和8,这是很简单的一种赋值,把a赋给b,b的改变不会影响到a的值,这种赋值的关系,存在于基本类型当中。比如字符串,数字,布尔值,undefind,{}。
下面我们来看看复杂类型当中的引用情况:
let a = [1,2,3];
let b = a;
b.push(4);
alert(a);
alert(b);
上面这种情况,很明显a b打印出来的值都为1,2,3,4,因为对象和函数都是引用的关系,下面我们把代码做一些变动。
let a = [1,2,3];
let b = a;
b = [1,2,3,4]
alert(a);
alert(b);
a b打印出来的值,就和上面不一样了,b的赋值并没有影响到a ,相当于重新开辟了一个内存空间。由于对象引用的这种设计,我们在实际开发中,会遇到一些奇奇怪怪的问题。
let obj = {
a:10
}
let obj2 = obj
obj2.a = 20
alert(obj.a)
由于共用同一个引用,此时弹窗的值为20。当我们使用一个对象,赋值给另一个对象时,对赋值的对象的操作,会影响原来的对象,因此我们就有了深拷贝和浅拷贝的说法。下面我们写一个简单的浅拷贝方法:
let obj = {
a:10
}
function copy(obj){
let newObj = {}
for(let attr in obj){
newObj[attr] = obj[attr]
}
return newObj
}
let obj2 = copy(obj)
obj2.a = 20
alert(obj.a)
运行代码,可以看到,弹窗的值为10,并没有受到新赋值的影响。但是这样的方法并不能处理对象嵌套对象的情况,比如:
let obj = {
a:{
b:10
}
}
function copy(obj){
let newObj = {}
for(let attr in obj){
newObj[attr] = obj[attr]
}
return newObj
}
let obj2 = copy(obj)
obj2.a.b = 20
alert(obj.a.b)
这样还修改了原有对象值,新旧对象,并没有起到相互隔离的效果,因为只拷贝了一层,所以叫做浅拷贝,下面我们递归处理多层,实现深拷贝。
let obj = {
a:{
b:10
}
}
function deepCopy(obj){
if(typeof obj !== 'object'){
return obj
}
let newObj = {}
for(let attr in obj){
newObj[attr] = deepCopy(obj[attr])
}
return newObj
}
let obj2 = copy(obj)
obj2.a.b = 20
alert(obj.a.b)