eslint报错:

  Use an object spread instead of `Object.assign` eg: `{ ...foo }`.(prefer-object-spread)

即:

  禁止使用以对象字面量作为第一个参数的 Object.assign,优先使用对象扩展。

示例:(注意:对象字面量)

Object.assign({}, foo)

改为:

{ ...foo }

思考一下:
Object.assign常用来浅拷贝,那扩展符赋值的对象是重新开辟的堆内存还是指向的扩展对象的堆内存?

    const a = { a: 'a' };
const b = { ...a };
console.log('b=', b); // b= {a: "a"}
a.a = 'c';
console.log('b变了吗', b); // b变了吗 {a: "a"}

  

  答案很明显,我想浅拷贝一个a, 扩展运算符和Object.assign都能浅拷贝对象。

  那数组会怎样?

  

    const a = ['a', 'b'];
const b = [...a];
console.log('b=', b); // b= ["a", "b"]
a[1] = 'c';
console.log('b变了吗', b); // b变了吗 ["a", "b"]

  很好,数组也能放心的浅拷贝;

  

  等等。。。

  

  如果是数组对象呢?

    const a = [{ a: 'a' }];
const b = [...a];
console.log('b=', JSON.stringify(b)); // b= [{"a":"a"}]
a[0].a = 'c';
console.log('b变了吗', JSON.stringify(b)); // b变了吗 [{"a":"c"}]

  变了,结果说明展开符只对数组里面的对象进行了展开,对象里面的属性还是指向的原来的内存地址,所以深拷贝行不通,目前来看和Object.assign的浅拷贝作用一样。

那...等等,

  

  Object.assign还有合并的作用,再来试试扩展符合并。

  

  

    const a = { a1: 'a1', a2: 'a2' };
const b = { b1: 'b1', a2: 'b2' };
const c = Object.assign({}, a, b);
const d = { ...a, ...b };
const e = { ...b, ...a };
console.log('c', c); // c {a1: "a1", a2: "b2", b1: "b1"}
console.log('d', d); // d {a1: "a1", a2: "b2", b1: "b1"}
console.log('e', e); // e {b1: "b1", a2: "a2", a1: "a1"}

   结果一样,Object.assign将b和a的属性合并到空对象里,相同属性会覆盖合并取后面的值,扩展符直接合并两个对象的属性,合并关系都是后面的覆盖前面的值。

   那么,合并数组呢?

    const a = ['a', 'b'];
const b = ['a', 'c'];
const c = Object.assign([], a, b);
const d = [...a, ...b];
console.log('c', c); // c ["a", "c"]
console.log('d', d); // d ["a", "b", "a", "c"]

   发生了什么?

   Object.assign处理数组时,会把数组视为对象,然后按顺序覆盖前面的值,所以b中的'a'覆盖了a中的'a', b中的'c'覆盖了a中的'b',而扩展符和concat方法一样合并数组。

   合并数组时,Object.assign和扩展符作用不一样了。

   

   那么,复杂数组呢?

    const a = [{ x: 'x', y: 'y' }];
const b = [{ z: 'z', y: 'm' }];
const c = Object.assign([], a, b);
const d = [...a, ...b];
console.log('c', JSON.stringify(c)); // c [{"z":"z","y":"m"}]
console.log('d', JSON.stringify(d)); // d [{"x":"x","y":"y"},{"z":"z","y":"m"}]
b[0].z = 'n';
console.log('c', JSON.stringify(c)); // c [{"z":"n","y":"m"}]
console.log('d', JSON.stringify(d)); // d [{"x":"x","y":"y"},{"z":"n","y":"m"}]

  

  Object.assign毫无悬念的后面的覆盖前面了(将数组看做对象时,属性就是下标),引用类型指向的还是原来的内存地址。

  

最后:

  

  虽然说Object.assign和...扩展符很多时候能混用,但对数组进行操作的时候一定要小心两者的区别,不然合并覆盖变成合并拼接,所以请牢记使用以对象字面量作为第一个参数的 Object.assign,优先使用对象扩展。

 

 


prefer-object-spread的更多相关文章

  1. [Python] Object spread operator in Python

    In JS, we have object spread opreator: const x = { a: '1', b: '2' } const y = { c: '3', d: '4' } con ...

  2. [Python] List & Object spread in Python

    def myfunc(x, y, z): print(x, y, z) tuple_vec = (, , ) dict_vec = {, , } >>> myfunc(*tuple_ ...

  3. js spread object

    What’s is the benefit / drawback of these two alternatives? Using object spread options = {...option ...

  4. ES6之Spread Operater拷贝对象

    译者按: 对象拷贝和合并使用展开运算符(Spread Operator)很方便! 原文: Master Javascript’s New, Cutting-Edge Object Spread Ope ...

  5. React——教程 && 零基础入门 && 从实践中学习(待续)

    Tutorial: Intro to React This tutorial doesn’t assume any existing React knowledge. Tip This tutoria ...

  6. vue.js组件化开发实践

    前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然 ...

  7. npm-bluebird使用

    API 注意 时刻注意return; 使用Promise.promisify简化对test(val, function(err, result){})的处理; 尽量避免使用deferred objec ...

  8. vuex 笔记

    Vuex 笔记 一个简单的状态管理 单一数据源: const sourceOfTruth = {} const vmA = new Vue({ data: sourceOfTruth }) const ...

  9. Javascript.ReactNative-2-javascript-syntax-in-react-native

    JavaScript Syntax in React Native Contents: Arrow Function Let+Const Default + Rest + Spread Destruc ...

  10. groovy-运算符

    算术和条件运算符 Groovy支”!”操作符,例如: 1 def expression = false 2 assert !expression 基于集合的运算符: Spread Operator ( ...

随机推荐

  1. PTA A1011&A1012

    A1011 World Cup Betting (20 分) 题目内容 With the 2010 FIFA World Cup running, football fans the world ov ...

  2. 操作DOM会影响WEB应用的性能

    平时在工作中,要优化自己开发的WEB应用的性能,一般是遵循以下几个原则: 1.减少网络请求. 2.压缩.合并静态资源文件,以此来减轻网络传输的带宽压力和资源消耗. 3.代码逻辑层面上的性能优化.比如减 ...

  3. java接收控制台输入

    java控制台输入语句: Scanner sc = new Scanner(System.in); 通过一个变量,例如 int r; r = sc.nextInt();   例子: public st ...

  4. 夯实Java基础系列5:Java文件和Java包结构

    目录 Java中的包概念 包的作用 package 的目录结构 设置 CLASSPATH 系统变量 常用jar包 java软件包的类型 dt.jar rt.jar *.java文件的奥秘 *.Java ...

  5. APP自动化测试的环境配置

    什么是Appium? 第三方自动化框架(工具),扩充了selenium webdriver 协议,在原有的基础上添加了移动端测试API selenium webdriver 指定了客户端到服务端的协议 ...

  6. 讨论c/c++计算小数的精度问题

    求出所有100以下整数与一位小数相乘等于相加的浮点数这个有Bug浮点数计算时精度会出现误差 除非使用非常精确的类型或限制浮点的位数 比如 #include <iostream> int m ...

  7. Ansible常用模块基本操作

    Ansible是一个系列文章,我会尽量以通俗易懂.诙谐幽默的总结方式给大家呈现这些枯燥的知识点,让学习变的有趣一些. 前言 对于任何一个框架,一个应用,为了更便于推广,便于使用,便于商业化,都会顺便提 ...

  8. Spring5源码解析-前奏:本地构建Spring5源码

    构建环境 macOS 10.13.6 JDK1.8 IntelliJ IDEA 2018.3.6 (Ultimate Edition) Spring v5.1.9.RELEASE Gradle 5.5 ...

  9. Vue学习系列(一)——初识Vue.js核心

    前言 vue.js是一套构建用户界面的渐进式框架,vue.js的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件. vue通过DOM事件操作和指令来进行视图层和模型层的相互通讯,会为每一 ...

  10. 无意间做了个 web 版的 JVM 监控端(前后端分离 React+Spring Boot)

    之前写了JConsole.VisualVM 依赖的 JMX 技术,然后放出了一个用纯 JMX 实现的 web 版本的 JConsole 的截图,今天源码来了. 本来就是为了更多的了解 JMX,第一步就 ...