ES8 中用对象合并前描述符保留属性的比较:__proto__与 Object.assign

阅读时长 4 分钟读完

在开发前端应用时,经常需要使用对象合并来整合各个模块的数据。但是在对象合并时,存在一些描述符(descriptor)的属性,比如对象的属性枚举顺序、属性是否可枚举等等,这些属性常常被忽略。然而,在某些情况下,我们需要保留这些描述符属性。ES8中,我们可以通过__proto__和Object.assign两种方式来实现这个目的。

proto

__proto__属性是一个内置属性,用来获取和设置对象的原型(prototype)。它是不推荐使用的,而且在ES6中已经被废弃。但在ES8中,__proto__的行为发生了改变,它可以被用来保留对象的描述符信息。具体地,我们可以使用如下代码来通过__proto__保留对象的描述符信息:

-- -------------------- ---- -------
----- ---- - --- -- -- ---
----- ---- - --- -- -- ---
--------------------------- ------

-------------------- -- -
-------------------- -- -
-------------------- -- -

----- ------------------ - ------------------------------------- -----
--------------------------- ---- --------------------

-------------------- -- -
-------------------- -- -
-------------------- -- -

在这段代码中,我们先创建了两个对象obj1和obj2,然后通过Object.setPrototypeOf方法将obj1设置为obj2的原型。这样,obj2就可以继承obj1中的属性和方法。接着,我们使用Object.getOwnPropertyDescriptor方法获取了obj1中属性a的描述符属性,并通过Object.defineProperty方法将它复制到了obj2中。这样,obj2中的a属性就拥有了obj1中a属性的描述符信息。

需要注意的是,__proto__属性必须放在对象合并前面才能正常工作。如果我们将obj2设置为obj1的原型,则可能会产生意外的结果。

Object.assign

Object.assign方法是ES6中引入的,也是对象合并中最常用的方法之一。在ES8中,Object.assign方法也可以被用来保留对象的描述符信息。具体地,我们可以使用如下代码来通过Object.assign保留对象的描述符信息:

-- -------------------- ---- -------
----- ---- - --- --- --- -- ---
----- ---- - --- --- --- -- --- ----
----- ---- - ----------------- ----- ------

---------------------- -- -
---------------------- -- -
-------------------- -- -----

----- ------------------ - ------------------------------------- -----
----------------------------- ---- --------------------

---------------------- -- -
---------------------- -- -
-------------------- -- -----

在这段代码中,我们先创建了两个对象obj1和obj2,然后使用Object.assign方法将它们合并到了obj3中。接下来,我们使用Object.getOwnPropertyDescriptor方法获取了obj1中属性a的描述符属性,并通过Object.defineProperty方法将它复制到了obj3中的a属性中。这样,obj3中的a属性就拥有了obj1中a属性的描述符信息。

需要注意的是,如果有多个来源对象的属性拥有相同的名称,则后面的属性会覆盖前面的属性。另外,Object.assign只会复制对象的自有属性,因此无法拷贝继承的属性和不可枚举的属性。

总结

通过对比__proto__和Object.assign两种方法,我们可以发现它们都可以用来保留对象的描述符信息。__proto__的使用较为简单,但是需要注意放置的位置。而Object.assign的使用则需要注意相同属性名的覆盖问题。在实际开发中,我们可以根据具体情况选择使用哪种方法。

参考资料

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/65ba2a1fadd4f0e0ff2b977a

纠错
反馈