问题:一个对象赋值给另外一个变量,之后这二个变量使用同一地址。一方改变,另一方跟着改变。
复合类型数据才这样。
// ===============基本数据类型=======================
let nowMsg = '多云'
let tomorrowMsg = nowMsg
tomorrowMsg = '雷阵雨'
nowMsg // 多云
tomorrowMsg // 雷阵雨
// ==============复合类型-对象=======================
let msg = { address : '北京'} // 对象类型
let newMsg = msg // 赋值
msg.address = '上海' // 更新地址
console.log(newMsg.address) // msg 改变后 newMsg 跟着改变 --- 上海
出现原因是:
基本类型如:Boolean,Number,String 等都是存储在栈。
复合类型如:Object,Array等存储在堆。
看如上图,在赋值中,数字字符串等赋值的是具体的值,可是 Object 对象赋值的是地址,赋值后二地址相同,所以指向的是相同对象。所以需要拷贝,从对象中拿到值后在进行赋值操作。
解决方法:
浅拷贝 ----- 对象
let meg = {address:'北京'}
let nowMsg = Object.assign({}, msg) // 拷贝一份。 复制 meg 目标上的值到 {} 上,既然拿到值就可以赋值啦。
// es6写法
let nowMsg = {...meg} // 拷贝一份。 es6 ...展开能获取到值,这样就不会赋值地址啦。
深拷贝 ---- 多次嵌套对象
let msg = {
address: '北京',
teacher: {
name: '狗蛋',
age: '38'
}}
let nowMsg = JSON.parse(JSON.stringify(msg)) // 深拷贝
// 这种方法缺点:
//* 会忽略 undefined
//* 不能序列化函数
//* 不能解决循环引用的对象
经过浅或者深拷贝后。。。二个变量(对象)地址不一样,指向的对象也不一样。