首页 > 解决方案 > Object.assign 的意外输出

问题描述

所以我有点惊讶:

Object.assign({}, Math)

它返回一个空对象。我这样做是为了设置我自己的数学模块,我可以用我自己的自定义功能进行扩展,所以我认为这样做很方便:

Object.assign({}, Math, { 
  sqrt: <my-sqrt-implementation>, 
  add: <my-add-implementation >,
})

但是我惊讶地发现数学条目没有包括在内,这是为什么呢?在我的控制台中,我得到:

Object.assign({}, Math)
> {}

出了什么问题,如何解决?

标签: javascriptobjectecmascript-6

解决方案


的属性Math是不可枚举的。Object.assign将仅复制可枚举和自己的属性:

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

因此,您应该遵循建议,并使用Object.getOwnPropertyNames(Math)获取自己的属性名称列表,然后Object.defineProperty()分配它们:

const props = Object.getOwnPropertyNames(Math)
const myMath = {}
props.forEach(prop => {
    Object.defineProperty(myMath, prop, Object.getOwnPropertyDescriptor(Math, prop))
})

myMath.sin(3.14)  // 0.00159265...

当然,Object.create在这里使用原型继承 ( ) 可能会更好。我提供此代码是因为它更接近于 的行为Object.assign,即赋值。


推荐阅读