众所周知,ES6中增加了对象的展开运算符,开发中我们经常把他用于变量的拷贝或合并来使用。用法是这样:
let a = {age: 18};
let b = {name: "张三", ...a};
console.log(b); // {name: "张三",age: 18}
当执行上述代码后,a和b是两个完全独立的变量,b的变化不会影响到a。
b.age = 20;
console.log(a.age) // 18
然而当a的属性中包含复杂数据类型时,b的复杂属性变化时会作用到a对应的属性上。
例如:
let a = {age: 18, father: {name: "张大爷"};
let b = {name: "张三", ...a};
b.father.name = "李大爷";
console.log(a.father.name); // 李大爷
结果是b的father变为李大爷以后,a的father也跟着变了,这显然不是我们想要的结果。
由此可见:对象的展开运算符是浅拷贝,对于对象内部的复杂数据类型他拷贝的是对象的引用,新对象的属性变化有可能引起原对象的变化。
数组的展开运算符也有同样的问题,数组中包含对象时,拷贝数组的话也是只拷贝了该对象的引用。
网友评论