1. 对象的引用赋值
//对象是引用类型(引用在c/c++中其实就是指针的意思)
const info = {name:'ytlll',age:18}
const obj = info
info.name = "ytl"
console.log(obj.name); //ytl
- 假设info的对象指向的是0x100的内存地址,该内存地址中保存的是name和age两个属性
- 创建obj = info 其实是把info的内存地址0x100 赋值给obj
- 所以obj所指向的内存地址也是0x100,他们两者指向的是同一个内存空间
- 当修改info的name后,打印obj的name就是修改后的值
2. 对象的浅拷贝
const info = {name:'ytlll',age:18,friend:{name:"kobe",height:1.98}}
// Object.assign 把info对象中的所有属性,都复制下来,拷贝到obj的内存地址(和info不是同一个内存地址)
const obj = Object.assign({},info)
info.name = 'ytl'
console.log(obj.name); //ytlll
info.friend.name = "jams"
console.log(obj.friend.name); //jams
-
通过Object.assign()的方法来做一次浅拷贝
-
把info内存地址中的所有属性复制下来后,保存到obj的内存地址中
-
这时候info和obj指向的内存地址是不一样的(比如:info:0x100,obj:0x101)
-
所以这时候,修改info中的name后,打印obj.name还是原来的值,不变
-
而info中的friend属性也是一个对象,假设地址指向的是0xaaa
-
obj中拷贝过来的friend的内存地址也是0xaaa
-
所以他们两的friend属性指向的内存地址是同一个
3. 对象的深拷贝
- 原生js实现深拷贝:
const info = {name:'ytlll',age:18,friend:{name:"kobe",height:1.98}}
const obj = JSON.parse(JSON.stringify(info))
info.friend.name = 'Jams'
console.log(obj.friend.name); //kobe
- 通过JSON.stringify先把info对象中的属性转为JSON字符串
- 再通过JSON.parse解析并赋值给obj
- 此时创建的obj和info就完全是两个对象
- 所以修改info.friend.name为Jams,obj.friend.name打印的依然是Kobe
使用lodash库
- 浅拷贝: _.clone(拷贝对象)
// 使用lodash来浅拷贝
const info = {name:'ytlll',age:18,friend:{name:"kobe",height:1.98}}
const obj = _.clone(info)
info.name = 'ytl'
console.log(obj.name); //ytlll
info.friend.name = "jams"
console.log(obj.friend.name); //jams
- 深拷贝
// 使用lodash来深拷贝
const info = {name:'ytlll',age:18,friend:{name:"kobe",height:1.98}}
const obj = _.cloneDeep(info)
info.friend.name = 'Jams'
console.log(obj.friend.name); //kobe