ES6 对象解构赋值(浅拷贝 VS 深拷贝)

Posted cckui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 对象解构赋值(浅拷贝 VS 深拷贝)相关的知识,希望对你有一定的参考价值。

对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。

拷贝对象

let aa = 
    age: 18,
    name: 'aaa'


 
let bb = ...aa;
console.log(bb);  // age: 18, name: "aaa"

合并对象

扩展运算符(...)可以用于合并两个对象

let aa = 
    age: 18,
    name: 'aaa'
 

let bb = 
    sex: '男'

  
let cc = ...aa, ...bb; 


// 等同于: 
// let cc = Object.assign(, aa, bb);


console.log(cc); // age: 18, name: "aaa", sex: "男"

拷贝并修改对象

在扩展运算符后面,加上自定义的属性,则扩展运算符内部的同名属性会被覆盖掉。

let aa = 
    age: 18,
    name: 'aaa'

 
let dd = ...aa, name: 'ddd';
 

// 等同于: 
// let dd = ...aa, ...name: 'ddd';
// let dd = Object.assign(, aa,  name: 'ddd');



console.log(dd); // age: 18, name: "ddd"

一般,在 redux 中修改 state 时,会用解构赋值的方法。

但是,解构后得到的新对象,相对于老对象,是浅拷贝,还是深拷贝?

例如,下面肯定是引用赋值:

let aa = 
    age: 18,
    name: 'aaa'


let bb = aa;
bb.age = 22;

console.log(aa.age); // 22

上面, 对象 bb 是 aa 的一个引用赋值。那么,如果使用解构赋值得到 bb 呢:

let aa = 
    age: 18,
    name: 'aaa'


let bb = ...aa;
bb.age = 22;

console.log(aa.age); // 18
  • 可见,改变 bb 的属性 age 的值,并不会改变对象 aa 的属性的 age 的值,所以,上面的例子bb是aa的一份拷贝
  • 但是,这个拷贝是只有一层的浅拷贝,还是深拷贝?
let aa = 
    age: 18,
    name: 'aaa',
    address: 
        city: 'shanghai'
    


let bb = ...aa;
bb.address.city = 'shenzhen';

console.log(aa.address.city);  // shenzhen

可见,aa 解构赋值到新对象 bb,只是进行了一层浅拷贝,对象 bb 中的属性(address)的属性(city)还是对象 aa 中属性的属性的引用。

如果像拷贝 aa 中的 city 属性,可以像下面处理:

let aa = 
    age: 18,
    name: 'aaa',
    address: 
        city: 'shanghai'
    


let bb = 
    ...aa,
    address: ...aa.address
;

bb.address.city = 'shenzhen';

console.log(aa.address.city);  // shanghai

以上是关于ES6 对象解构赋值(浅拷贝 VS 深拷贝)的主要内容,如果未能解决你的问题,请参考以下文章

ES6的解构赋值与深拷贝和浅拷贝

js对象浅拷贝有解构赋值,assign2个方法吗?

es6划重点

js中的深拷贝与浅拷贝

C++中,啥是深拷贝?啥是浅拷贝?

什么是深拷贝和浅拷贝以及如何实现深拷贝