Object.assign()的用例不好 - 简单示例 [英] Poor Use Case of Object.assign() - Simple Example

查看:133
本文介绍了Object.assign()的用例不好 - 简单示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆