Object.assign()的用例不好 - 简单示例

时间:2017-08-19 13:34:46

标签: javascript object prototype

我正在阅读Object.assign()上的MDN docs,并发现了一个我不理解的短语:

  

Object.assign()方法仅将可枚举和自己的属性从源对象复制到目标对象。它在源上使用[[Get]],在目标上使用[[Set]],因此它将调用getter和setter。因此,它分配属性而不仅仅是复制或定义新属性。如果合并源包含getter,这可能使它不适合将新属性合并到原型中。为了将属性定义(包括它们的可枚举性)复制到原型中,应该使用Object.getOwnPropertyDescriptor()和Object.defineProperty()。

特别是这一行:

  

如果合并源包含getter,这可能使它不适合将新属性合并到原型中。

我不确定提倡反对使用Object.assign是一个很好的例子。

1 个答案:

答案 0 :(得分:8)

getter 是属性的访问器函数,它返回属性的值。这是一个带有getter的对象:



var obj = {
    get example() {
        console.log("getter was called");
        return Math.floor(Math.random() * 100);
    }
};
console.log(obj.example);
// Note no () ---------^




请注意,当我们读取example属性的值时,即使函数看起来不像函数调用,函数也会运行。

MDN文档的部分内容是Object.assign调用 getter,它不会在目标对象上创建等效的getter。所以:



var obj = {
    get example() {
        console.log("getter was called");
        return Math.floor(Math.random() * 100);
    }
};
var obj2 = Object.assign({}, obj); // calls getter
console.log(obj2.example);         // just has a simple value
console.log(obj2.example);         // same value, no call
console.log(obj2.example);         // same value, no call




obj' example属性有一个getter,但obj2 example属性只是一个简单的value属性。 Object.assign没有复制获取者,只是抓住了获取者的当前值并将其分配给obj2.example

可以复制getter,而不是Object.assign



function copyProperties(target, source) {
    Object.getOwnPropertyNames(source).forEach(name => {
        Object.defineProperty(
            target,
            name,
            Object.getOwnPropertyDescriptor(source, name)
        );
    });
    return target;
}
var obj = {
    get example() {
        console.log("getter was called");
        return Math.floor(Math.random() * 100);
    }
};
var obj2 = copyProperties({}, obj); // calls getter
console.log(obj2.example);          // calls getter
console.log(obj2.example);          // calls getter
console.log(obj2.example);          // calls getter




当然,如果getter不是为了在对象之间复制而设计的(例如,如果明确使用example的getter obj),则可能会出现意外结果