ES6扩展运算符浅拷贝

阮一峰老师的es6入门里讲数组的扩展时有下面的内容,a3和a4是浅拷贝,如果修改了引用指向的值,会同步反映到新数组,但为什么修改了a1 a2的值后,a3 a4的值并没有改变?
(2)合并数组

扩展运算符提供了数组合并的新写法。

const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

不过,这两种方法都是浅拷贝,使用的时候需要注意。

const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];

const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];

a3[0] === a1[0] // true
a4[0] === a1[0] // true

上面代码中,a3a4是用两种不同方法合并而成的新数组,但是它们的成员都是对原数组成员的引用,这就是浅拷贝。如果修改了引用指向的值,会同步反映到新数组。

阅读 2k
2 个回答

你指的修改 a1、a2 的值,是这么改:

a1 = [{ foo: 2}];

还是这么改:

a1[0].foo = 2

前者是直接修改 a1 的引用,自然不会影响 a3,a4

楼上说的第二种方法只是修改a1指向的内容的值,内容的地址没有变,所以a3 a4的值会跟着变。 第一种方法是对a1直接赋值一个新的数组,相当于a1指向的地址变了,此时a3 a4还是指向之前的地址,当然不会改变

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题