在ES6中新增了扩展运算符可以对数组和对象进行操作。有时候会遇到数组和对象的拷贝,可能会用到扩展运算符。那么这个扩展运算符到底是深拷贝还是浅拷贝呢?
一.、使用扩展运算符拷贝
首先是下面的代码。
let a = [1,2,3]; let b = [...a];
a == b // false
结果是false,这是很容易知道的,毕竟这个赋值操作符是有区别的。接下来将数组的值进行改变,又会怎样呢;
let a = [1,2,3]; let b = [...a]; a[0] = 11; console.log(a); // [ 11, 2, 3 ] console.log(b); // [ 1, 2, 3 ]
发现a的值发生改变之后b的值并没有发生改变。所以就是深拷贝了吗?别急,接下来将数组中的元素设为引用类型。
let a = [1,2,[1,2,3]]; let b = [...a]; a[2][1] = 11; console.log(a); // [ 1, 2, [ 1, 11, 3 ] ] console.log(b); // [ 1, 2, [ 1, 11, 3 ] ]
console.log(a[2] === b[2]); // true
这次的结果就有意思了,如果改变数组中的引用类型的元素中的值,此时a和b的值都会改变,并且a和b中的引用类型全等,也就是说地址是相同的。那么为什么是这样的呢?
二.、原因
首先此分析仅为本人目前的认知。
对于数组中的扩展运算符只是一个浅拷贝,仅对引用类型数据的第一层进行了拷贝,而倘若再深的层次就不会进行拷贝。
另外对象的扩展运算符和数组是一样的。
let a = { name : "Jyy", msg : { age : 29 } } let b = {...a}; console.log(a == b); // false console.log(a.msg == b.msg); // true; a.msg = { age : "28" } console.log(a); // { name: 'Jyy', msg: { age: '28' } } console.log(b); // { name: 'Jyy', msg: { age: 29 } }
a.msg.age = 28
console.log(a); // { name: 'Jyy', msg: { age: 28 } } console.log(b); // { name: 'Jyy', msg: { age: 28 } }