JavaScript的浅拷贝与深拷贝

相信大多数人在vue中都遇到过一个问题,就是对象变量a赋值给一个新的变量b,在修改b属性时 a也被修改了



这个准确的说不是vue的特点, 而是js的,估计是为了性能和效率优化,当对象变量赋值时,传递的是引用,相当于两个变量指向共同一个内存地址;

1
2
3
4
5
6
7
8
let test = { name:'特朗普' }
let woc = test
woc.name = "马克龙"
console.log(woc)
console.log(test)
---
{ name: '马克龙' } // woc
{ name: '马克龙' } // test



所以导致了, 上述问题的发生; 然而在js的5个基础类型中并不会使用引用赋值, 而且解决办法就是用深浅拷贝

浅拷贝

1
Object.assign()

如果我没记错的话, 好像是es6的特性, 浏览器要考虑ie和老旧浏览器解释引擎的问题; nodejs typescript之类的不用考虑, 他们会经过一个编译的工序使其兼容较早的es规范




使用示例

1
2
3
4
5
6
7
8
9
10
let test = { name: 66, sex:0}
let woc = Object.assign({}, test)

woc.sex = 7
console.log(woc)
console.log(test)

----
{ name: 66, sex: 7 } // woc
{ name: 66, sex: 0 } // test

注意:叫浅拷贝是有原因的, 它只能让一维属性不采用引用方式,如果你的对象中包涵对象、数组请使用深拷贝

深拷贝

1
2
JSON.stringify()
JSON.parse()

把对象变量转换成字符串, 再解析给另一个变量。 完全重新解析的, 自己申请开辟内存空间,就是感觉上不怎么优雅;

1
2
3
4
5
6
7
8
let test = { name: 66, sex:0}
let woc = JSON.parse(JSON.stringify(test))
woc.sex = 5
console.log(woc)
console.log(test)
---
{ name: 66, sex: 5 } // woc
{ name: 66, sex: 0 } // test