我正在阅读Object.assign()
上的MDN docs,并发现了一个我不理解的短语:
Object.assign()方法仅将可枚举和自己的属性从源对象复制到目标对象。它在源上使用[[Get]],在目标上使用[[Set]],因此它将调用getter和setter。因此,它分配属性而不仅仅是复制或定义新属性。如果合并源包含getter,这可能使它不适合将新属性合并到原型中。为了将属性定义(包括它们的可枚举性)复制到原型中,应该使用Object.getOwnPropertyDescriptor()和Object.defineProperty()。
特别是这一行:
如果合并源包含getter,这可能使它不适合将新属性合并到原型中。
我不确定提倡反对使用Object.assign
是一个很好的例子。
答案 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
),则可能会出现意外结果