object-assign合并对象

1. Object.assign()

对于合并对象操作, ECMAScript 6 中提供了一个函数:

Object.assign(target, source);

这个方法会将所有可枚举 [1] 的自由属性从 source 复制到 target 。并且它返回(修改后的) target 。关于这个函数最终签名至今还在争论,最终还有可能支持多个来源(被复制的对象)。即便是使用简单的签名(signature),也可以处理多个来源,使用Array.prototype.reduce :

[source1, source2 source3].reduce(Object.assign, target);

1.1 属性名:字符串或者符号

在 ECMAScript 6中,属性名称可以是字符串或者 符号 (symbols)。后者是一种新的唯一标识符;基本上使用符号作为属性名是不可能有命名冲突的。Object.assign() 支持字符串或者符号作为属性名。

原文中叫做: property keys, 表示对象的键,属性就干脆译作属性名。如有误,请指正。

1.2 复制与赋值

目标对象中的属性是通过赋值操作创建的(内置的[[Put]]操作)。这就意味着如果target 拥有(自身或者继承的) setters [1] ,这回在复制的过程中调用。一种可替代的方式就是定义新的属性 [2] ,总是创建新的自由属性而从不调用 setters。原本对于Object.assign() 的一个变体的提议就是使用定义替代赋值的方式。但是该提议被 ECMAScript 6 拒绝了(在后续新版中可能会重新考虑)。

2. Object.assign() 用例

2.1 设置实例属性

构造器的任务就是设置实例属性。对于这个任务来说变量名总是被认为是冗余的:

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
}

我比较喜欢下面的语法,它完全删除了冗余的代码(CoffeeScript 和 TypeScript都可以做到,但是我更喜欢下面这种语法):

class Point {
    constructor(this.x, this.y) {
    }
}

Object.assign() 至少也能够让你避免一些冗余:

class Point {
    constructor(x, y) {
        Object.assign(this, {x, y});
    }
}

在 ECMAScript 6 中, {x, y} 是 {x: x, y: y} 的一种缩写形式。

2.2 给对象添加方法

在 ECMAScript 5 中,可以使用函数表达式来给对象添加方法:

MyClass.prototype.foo = function(arg1, arg2) {
    // ...
};

在 ECMAScript 6 中对于方法 [3] 有一个更简洁的语法。这就要感谢Object.assign() 了,但是你也不必抛弃原来的语法:

Object.assign(MyClass.prototype, {
    foo(arg1, arg2) {
        ...
    }
});

2.3 克隆对象

也可以使用 Object.assign() 来克隆一个对象(浅克隆):

var copy = Object.assign({__proto__: obj.__proto__}, obj);

如果只对对象的自由属性感兴趣,那更简单:

var copy = Object.assign({}, obj);

参考

[1]. JavaScript中的对象属性

[2]. JavaScript中的属性: 定义与赋值

[3]. ECMAScript 6中可调用的实体

https://github.com/sindresorhus/object-assign/blob/master/index.js

posted on 2016-02-13 15:38  dhj  阅读(407)  评论(0编辑  收藏  举报

导航