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

qar*_*dso 8 javascript prototype object

我读的MDN文档Object.assign()和跨一个短语,我不明白传来:

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

特别是这一行:

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

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

T.J*_*der 9

是返回属性的值的属性访问器功能.这是一个带有getter的对象:

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

请注意,当我们读取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
Run Code Online (Sandbox Code Playgroud)

objexample酒店有一个getter,但obj2example属性只是一个简单的价值属性.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
Run Code Online (Sandbox Code Playgroud)

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