ES6的Object.assign()详解
混入( Mixin )是在 JS 中组合对象时最流行的模式。在一次混入中,一个对象会从另一个对
象中接收属性与方法。很多 JS 的库中都有类似下面的混入方法:
function mixin(receiver, supplier) { Object.keys(supplier).forEach(function(key) { receiver[key] = supplier[key]; }); return receiver; }
mixin() 函数在 supplier 对象的自有属性上进行迭代,并将这些属性复制到 receiver 对
象(浅复制,当属性值为对象时,仅复制其引用)。这样 receiver 对象就能获得新的属性
而无须使用继承,正如下面代码:
function EventTarget() { /*...*/ } EventTarget.prototype = { constructor: EventTarget, emit: function() { /*...*/ }, on: function() { /*...*/ } }; var myObject = {}; mixin(myObject, EventTarget.prototype); myObject.emit("somethingChanged");
此处 myObject 对象接收了 EventTarget.prototype 对象的行为,这给了它分别使用 emit()
与 on() 方法来发布事件与订阅事件的能力。
此模式已经足够流行,于是 ES6 就添加了 Object.assign() 方法来完成同样的行为。该方法
接受一个接收者,以及任意数量的供应者,并会返回接收者。方法名称从 mixin() 变更为
assign() 更能反映出实际发生的操作。由于 mixin() 函数使用了赋值运算符( = ),它
就无法将访问器属性复制到接收者上, Object.assign() 体现了这种区别。
各式各样的库中都有相似但名称不同的方法,其基本功能相同,流行的替代方法包括
extend() 或 mix() 。而 ES6 也曾在 Object.assign() 之外短暂存在一个
Object.mixin() 方法,二者的主要差异在于 Object.mixin() 也会复制访问器属性,但
考虑到 super 的使用(详见本章的“使用 super 引用的简单原型访问”小节),此方法最
终被移除了。
你可以在任意曾使用 mixin() 函数的地方使用 Object.assign() ,此处有个例子:
function EventTarget() { /*...*/ } EventTarget.prototype = { constructor: EventTarget, emit: function() { /*...*/ }, on: function() { /*...*/ } } var myObject = {} Object.assign(myObject, EventTarget.prototype); myObject.emit("somethingChanged");
Object.assign() 方法接受任意数量的供应者,而接收者会按照供应者在参数中的顺序来依次
接收它们的属性。这意味着在接收者中,第二个供应者的属性可能会覆盖第一个供应者的,
这在下面的代码片段中就发生了:
var receiver = {};
Object.assign(receiver,
{
type: “js”,
name: “file.js”
},
{
type: “css”
}
);
console.log(receiver.type); // “css”
console.log(receiver.name); // “file.js”
receiver.type 的值为 “css” ,这是因为第二个供应者覆盖了第一个供应者的值。
Object.assign() 方法并不是 ES6 的一项重大扩展,但它确实将很多 JS 库中的一个公共方
法标准化了。
第四章 扩展的对象功能
80