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对象