【ES6】对象的扩展2
2016-09-13 07:51
211 查看
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
var obj1 = {a: {b: 1}}; var obj2 = Object.assign({}, obj1); obj1.a.b = 2; obj2.a.b // 2
上面代码中,源对象
obj1的
a属性的值是一个对象,
Object.assign拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。
对于这种嵌套的对象,一旦遇到同名属性,
Object.assign的处理方法是替换,而不是添加。
var target = { a: { b: 'c', d: 'e' } } var source = { a: { b: 'hello' } } Object.assign(target, source) // { a: { b: 'hello' } }
上面代码中,
target对象的
a属性被
source对象的
a属性整个替换掉了,而不会得到
{ a: { b: 'hello', d: 'e' } }的结果。这通常不是开发者想要的,需要特别小心。
有一些函数库提供
Object.assign的定制版本(比如Lodash的
_.defaultsDeep方法),可以解决浅拷贝的问题,得到深拷贝的合并。
注意,
Object.assign可以用来处理数组,但是会把数组视为对象。
Object.assign([1, 2, 3], [4, 5]) // [4, 5, 3]
上面代码中,
Object.assign把数组视为属性名为0、1、2的对象,因此目标数组的0号属性
4覆盖了原数组的0号属性
1。
常见用途
Object.assign方法有很多用处。
(1)为对象添加属性
class Point { constructor(x, y) { Object.assign(this, {x, y}); } }
上面方法通过
Object.assign方法,将
x属性和
y属性添加到
Point类的对象实例。
(2)为对象添加方法
Object.assign(SomeClass.prototype, { someMethod(arg1, arg2) { ··· }, anotherMethod() { ··· } }); // 等同于下面的写法 SomeClass.prototype.someMethod = function (arg1, arg2) { ··· }; SomeClass.prototype.anotherMethod = function () { ··· };
上面代码使用了对象属性的简洁表示法,直接将两个函数放在大括号中,再使用assign方法添加到SomeClass.prototype之中。
(3)克隆对象
function clone(origin) { return Object.assign({}, origin); }
上面代码将原始对象拷贝到一个空对象,就得到了原始对象的克隆。
不过,采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码。
function clone(origin) { let originProto = Object.getPrototypeOf(origin); return Object.assign(Object.create(originProto), origin); }
(4)合并多个对象
将多个对象合并到某个对象。
const merge = (target, ...sources) => Object.assign(target, ...sources);
如果希望合并后返回一个新对象,可以改写上面函数,对一个空对象合并。
const merge = (...sources) => Object.assign({}, ...sources);
(5)为属性指定默认值
const DEFAULTS = { logLevel: 0, outputFormat: 'html' }; function processContent(options) { let options = Object.assign({}, DEFAULTS, options); }
上面代码中,
DEFAULTS对象是默认值,
options对象是用户提供的参数。
Object.assign方法将
DEFAULTS和
options合并成一个新对象,如果两者有同名属性,则
option的属性值会覆盖
DEFAULTS的属性值。
注意,由于存在深拷贝的问题,
DEFAULTS对象和
options对象的所有属性的值,都只能是简单类型,而不能指向另一个对象。否则,将导致
DEFAULTS对象的该属性不起作用。
相关文章推荐
- 网络编程(8)—— IP地址和域名之间的转换
- 七种网卡绑定模式
- POJ 1077(HDU 1043)Eight(八数码DBFS)
- 第36篇 翻译webrtc官方文档(三)及PHP命名空间(二)
- 有些东西再忙也要做
- 有些东西再忙也要做
- HTTP协议1
- 从零开始学 Java - Spring 支持 CORS 请求踩的坑
- 配置nagios监控oracle,check_oracle_health
- [C#] 走进异步编程的世界 - 剖析异步方法(下)
- 唐灵波_2015级精英班_2015~2016第一学期总结
- Linux 压缩 解压 安装 命令总结
- OSChina 周二乱弹 ——爱酱,老司机前来自首了
- Cisco Packet Tracer 7.0 简单的使用教程
- org/springframework/core/MethodClassKey
- 转载 C#使用Salt + Hash来为密码加密
- EF配置文件初始化数据库 codefirst
- iOS-AVSpeechSynthesizer语音合成
- Line Reflection
- 领域模型(转)