Object.assign()的用例不好 - 简单示例 [英] Poor Use Case of Object.assign() - Simple Example
问题描述
我正在阅读 MDN docs on Object.assign()
并遇到一个我不理解的短语:
I'm reading the MDN docs on Object.assign()
and came across one phrase that I don't understand:
Object.assign()方法仅将可枚举和自己的属性从源对象复制到目标对象。它在源上使用[[Get]],在目标上使用[[Set]],因此它将调用getter和setter。因此,它分配属性而不仅仅是复制或定义新属性。如果合并源包含getter,这可能使它不适合将新属性合并到原型中。为了将属性定义(包括它们的可枚化性)复制到原型中,应该使用Object.getOwnPropertyDescriptor()和Object.defineProperty()。
The Object.assign() method only copies enumerable and own properties from a source object to a target object. It uses [[Get]] on the source and [[Set]] on the target, so it will invoke getters and setters. Therefore it assigns properties versus just copying or defining new properties. This may make it unsuitable for merging new properties into a prototype if the merge sources contain getters. For copying property definitions, including their enumerability, into prototypes Object.getOwnPropertyDescriptor() and Object.defineProperty() should be used instead.
特别是这一行:
如果合并源包含getter,这可能使它不适合将新属性合并到原型中。
This may make it unsuitable for merging new properties into a prototype if the merge sources contain getters.
我不确定如何提倡反对使用 Object.assign
。
I'm not exactly sure what a good example is for advocating against using Object.assign
.
推荐答案
getter 是一个返回属性值的属性的访问函数。这是带有getter的对象:
A getter is an accessor function for a property that returns the property's value. This is what an object with a getter looks like:
var obj = {
get example() {
console.log("getter was called");
return Math.floor(Math.random() * 100);
}
};
console.log(obj.example);
// Note no () ---------^
请注意,当我们读取示例
属性的值时,即使它没有运行,该函数也会运行看起来像一个函数调用。
Notice that when we read the value of the example
property, the function gets run even though it doesn't look like a function call.
MDN文档的部分内容是 Object.assign
将调用 getter,它不会在目标对象上创建等效的getter。所以:
What that part of the MDN docs is saying is that Object.assign
will call that getter, it won't create an equivalent getter on the target object. So:
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
的示例
属性有一个getter,但 obj2
的 example
property只是一个简单的value属性。 Object.assign
没有复制getter,它只是获取了getter的当前值并将其分配给了 obj2.example
。
obj
's example
property has a getter, but obj2
's example
property is just a simple value property. Object.assign
didn't copy the getter, it just grabbed the getter's current value and assigned it ot obj2.example
.
你可以复制getter,而不是 Object.assign
:
You can copy getters, just not with 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不是设计用于在对象之间复制(例如,如果示例
的getter显式使用 obj
),您可能会遇到意外结果。
Of course, if the getter isn't designed to be copied between objects (for instance, if example
's getter explicitly used obj
), you may get unexpected results.
这篇关于Object.assign()的用例不好 - 简单示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!