prefer-object-spread
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,优先使用对象扩展。
最新文章
- DP专题训练之HDU 1231 	最大连续子序列
- unix-ln 命令
- php 显示内存 释放内存
- jquery offset() 与position()方法的区别
- HDU Destroy Transportation system(有上下界的可行流)
- 想知道吗?CTO 比普通程序员强在哪?
- work1
- Win7下Boost库的安装
- MySQL常用函数 转载
- 在QT中使用Irrlicht引擎的方法与步骤
- ajax(ajax开发)
- (续)顺序表之单循环链表(C语言实现)
- Android Gson深入分析
- KbmMW两种查询结果集通讯方式
- HDU 1695 GCD 欧拉函数+容斥原理+质因数分解
- [google面试CTCI]1-3.字符串去重
- java中volatile不能保证线程安全
- 004.Create a web app with ASP.NET Core MVC using Visual Studio on Windows --【在 windows上用VS创建mvc web app】
- go interface接口
- K8S学习笔记之Kubernetes 部署策略详解
热门文章
- [VB.NET Tips]Select Case语句拾遗
- Jupyter Notebook安装和使用详情(你不懂我......)
- springboot 项目打包部署后设置上传文件访问的绝对路径
- Mybatis的xml文件对大于号小于号的特殊处理!
- .net core 3.0 Signalr - 实现一个业务推送系统
- 快学Scala 第八课 (嵌套类)
- 使用 Chrome 对长网页(知乎、微信公众号文章)进行完整截图
- 什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing )?
- Docker学习1-CentOS 7安装Docker
- 移动端meta设置大全