1、对象的引用赋值
let info = {
name: '小亮'
}
let obj = info
obj.name = '小明'
console.log(info.name) // 小明
通过上面的案例,我们发现改变对象obj
的name
属性,对象info
的属性也会随着改变。这里我们需要搞清楚一点,就是在定义info
这个对象的时候,首先在栈内存中会创建一个变量(即info
),然后在堆内存里创建一个对象用来保存数据。这里的info
在栈内存中实际上保存的是一个引用(在一些语言里面也叫指针),这个引用会指向堆内存里创建出来的对象。let obj = info
这里实际上是将对象在堆内存里的地址赋值给了obj
,即obj
和info
指向同一个对象,所以改变obj
对象的name
属性,info
对象也会随之改变。
2、对象的浅拷贝
let info = {
name: '小亮',
friend: {
name: '小华'
}
}
let obj = Object.assign({}, info)
obj.name = '小红'
console.log(info.name) // 小亮
obj.friend.name = '小明'
console.log(info.friend.name) // 小明
如上图所示,对info
对象的浅拷贝实际上是通过对象的assign方法实现的,这个方法会在堆内存中重新创建一个对象。所以此时的obj
实际上是另外一个对象,对obj
的name
属性的修改自然不会影响到info
对象。这里要注意,如果被拷贝的对象内部的属性的值也是一个对象(如上图info
对象的friend
属性),那么拷贝对象相对应的属性实际上保存的是一个引用,这也是浅拷贝和深拷贝最主要的区别。
3、对象的深拷贝
let info = {
name: '小亮',
friend: {
name: '小华'
}
}
let obj = JSON.parse(JSON.stringify(info))
obj.friend.name = '小明'
console.log(info.friend.name) // 小华
在开发中,我们通常会通过将对象转换成json格式数据,然后又将json格式数据转换成对象的方式来实现对象的深拷贝,这样做会在堆内存里面重新创建出一个具有和原对象相同数据的新对象,不同于浅拷贝的是,即使对象内部的属性的值是对象,也会为其重新创建一个具有相同数据的新对象。因此如上图所示,对obj.friend.name
的修改不会影响到info
对象