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

拷贝对象

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. java GC jvm 内存分布 和新生代,老年代,永久代,(详细)

    如果大家想深入的了解JVM,可以读读周志明<深入理解Java虚拟机:JVM高级特性与最佳实践> 需要掌握的东西,包括以下内容.判断对象存活还是死亡的算法(引用计数算法.可达性分析算法).常 ...

  2. redhat quay 集成镜像构建

    redhat quay 可以类似docker hub 那样进行镜像的构建,以下是一个学习,但是在测试中发现流程是可以通的,但是 quay 在对于dockerfile 内容处理上有bug,造成build ...

  3. 从rpm包提取rpm spec 的几种方法

    包含了源码包 先安装,然后在rpmbuild 目录直接可以查看文件 不用安装 ,使用rpm2cpio rpm2cpio myrpm.src.rpm | cpio -civ '*.spec' 没有源码 ...

  4. 请用js语言实现sort排序函数,要求:sort([4,5,2,-1,0])返回[-1,0,2,4,5]

    Array.prototype.sort1=function(fn){ var len=this.length; while(len>0){ for(var i=0;i<len;i++){ ...

  5. 安卓设备连接Mac的简单方法

    mac设备是苹果出品的桌面系统,以高冷而闻名,不同于我们平常使用的windows系统,mac系统对软件硬件的兼容性很差,将iOS 设备(iPhone.iPad和iPod)连接至Mac是一件很简单的事, ...

  6. 第10组 Beta版本演示

    一.小组信息 组长博客链接 组名:凹秃曼 组内成员 学号 组员 031702240 童景霖(组长) 031702225 叶泽林 031702246 陈鸿立 031702201 万本琳 03170222 ...

  7. 每日一问:Android 中内存泄漏都有哪些注意点?

    内存泄漏对每一位 Android 开发一定是司空见惯,大家或多或少都肯定有些许接触.大家都知道,每一个手机都有一定的承载上限,多处的内存泄漏堆积一定会堆积如山,最终出现内存爆炸 OOM. 而这,也是极 ...

  8. 如何实现有返回值的多线程 JAVA多线程实现的三种方式

    可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口.执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable ...

  9. 京东联盟开发(6)——推广链接解析SKUID

    1.从推广方案中分析出价格及推广码 $keyword = " [京东]长虹(CHANGHONG) L3 老人手机 移动/联通2G 老年机 双卡双待 咖啡 原价:168.00元 券后价:163 ...

  10. IO流—其他流

    内存操作流 这个流不关联任何文件,只能在内存中数据,自己在内存中维护着一个缓冲区,我们可以往他维护的缓冲区不断的写入数据,也可以从缓冲区中取出我们写入的数据 ByteArrayOutputStream ...