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

拷贝对象

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 深拷贝)的更多相关文章

  1. ES6 对象解构

    ES6 对象解构 第一眼看到,什么鬼? const { body } = document `` 其实等于: const body = document.body ``` http://es6.rua ...

  2. ES6变量解构赋值

    ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构ES6之前我们申明多个变量需要按照下面的方法: let l a=1; let b=2; let c=3; let d=4; ...

  3. ES6 的解构赋值前每次都创建一个对象吗?会加重 GC 的负担吗?

    本文来源于知乎上的一个提问. 为了程序的易读性,我们会使用 ES6 的解构赋值: function f({a,b}){} f({a:1,b:2}); 这个例子的函数调用中,会真的产生一个对象吗?如果会 ...

  4. es6 -- 与解构赋值默认值结合使用

    参数默认值可以与解构赋值的默认值,结合起来使用. function foo({x, y = 5}) { console.log(x, y) } foo({}) // undefined 5 foo({ ...

  5. ES6(解构赋值)

    解构赋值 1.什么是解构赋值? 在语法上,就是赋值的作用,解构为(左边一种解构.右边一种解构,左右一一对应进入赋值) 2.解构赋值的分类. 1.左右为数组即为数组解构赋值:2.左右为对象即为对象解构赋 ...

  6. ES6初识-解构赋值

    数组解构赋值 [a,b]=[1,2]; . 方法返回 function f(){ return [1,2] } let a,b; [a,b]=f();//a=1,b=2   function f1() ...

  7. 关于ES6 的对象解构赋值

    之 前写了关于ES6数组的解构 现在 go on ; 解构不仅可以用于数组,还可以用于对象: 对象的解构和数组有一个重要的不同.数组的元素是按次序排列的,变量的取值是由他的位置决定的:而对象的属性没有 ...

  8. 【ES6 】ES6 解构赋值--对象解构赋值

    对象的解构与数组有一个重要的不同. 数组的元素是按次序排列的,变量的取值由它的位置决定 而对象的属性没有次序,变量必须与属性同名,才能取到正确的值. 基本用法 如果解构失败,变量的值等于undefin ...

  9. 进军es6(2)---解构赋值

    本该两周之前就该总结的,但最近一直在忙校招实习的事,耽误了很久.目前依然在等待阿里HR面后的结果中...但愿好事多磨!在阿里的某轮面试中面试官问到了es6的掌握情况,说明es6真的是大势所趋,我们更需 ...

随机推荐

  1. shell 命令行

    转:Davygeek 1. -eq           //等于 -ne           //不等于 -gt            //大于 (greater ) -lt            / ...

  2. Spring Boot 知识笔记(全局异常)

    通过ControllerAdvice和ExceptionHandler捕获异常和错误信息,向前端返回json格式的状态码及异常描述信息. 1.新建一个Controller,抛出一个异常. packag ...

  3. Java 抽象类 抽象方法 接口

    #抽象类 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不能实例化 ...

  4. 用rust实现高性能的数据压缩工具

    https://github.com/richox/orz [求watch/star/fork] rust是一门新兴的程序语言,有着不输C/C++的性能.简洁精练的语法和可靠的内存安全性.orz是一款 ...

  5. 微信小程序跳转函数总结

    微信小程序跳转函数总结 ​ 笔者在微信小程序前端的开发过程中,在不同的情况下遇到了需要使用不同的页面跳转逻辑的情况,以下是我对这些函数的使用场景的一个总结介绍. wx.navigateTo 这是最常用 ...

  6. MySQL5.7调优参数

    1. 更改MySQL Data File位置 datadir=/data/mysqlsocket=/data/mysql/mysql.sock 2. 调整OS参数 * soft nproc 10240 ...

  7. Java一个对象占用多少字节

    虚拟机:Java HotSpot(TM) 64-Bit Server VM (25.221-b11, mixed mode) 对象的内存以字节为单位,且必须是8的倍数,它的构成由3部分组成:对象头+实 ...

  8. OpenCV+TensorFlow图片手写数字识别(附源码)

    初次接触TensorFlow,而手写数字训练识别是其最基本的入门教程,网上关于训练的教程很多,但是模型的测试大多都是官方提供的一些素材,能不能自己随便写一串数字让机器识别出来呢?纸上得来终觉浅,带着这 ...

  9. 使用Ajax (put delete ) django原生CBV 出现csrf token解决办法

    原因 django原生CBV中对于 Ajax put 或 delete 请求进行封装时,会把请求数据放在 request.body里, 所以获取不到csrf token 方式一: 关闭csrf 中间件 ...

  10. Python 的文件保存路径

    1.保存在当前代码同级的目录下: 2.保存在代码文件夹外面一层的新文件夹(data文件夹与代码文件夹同级)里: 3.保存在下一级的子文件夹里