来自Object.assign的意外输出

时间:2018-10-16 23:29:51

标签: javascript object ecmascript-6

所以我对此感到有些惊讶

Object.assign({}, Math)

哪个返回了一个空对象。我这样做是为了建立自己的数学模块,以便可以扩展自己的自定义功能,因此我认为这样做很方便:

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

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

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

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

3 个答案:

答案 0 :(得分:5)

Math的属性不是enumerableObject.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的行为(即分配)更紧密地匹配。

答案 1 :(得分:3)

来自:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

  

Object.assign()方法仅将可枚举的属性和自己的属性从源对象复制到目标对象

Math属性不可枚举或不可拥有。

示例:

enter image description here

  

如何解决?

使用Object.create,例如

var MyMath = Object.create(Math);
MyMath.sqrt = function () {
};

答案 2 :(得分:0)

Math对象下的属性和方法设置为non-iterableObject.assign尝试复制它们时,它们不会显示。

如果您将自己的属性添加到Math对象中,则会看到已找到该属性并将其复制。

另一方面,

Object.create应该做您想要的事情。

// You shouldn't ever really do this.
Math.testProperty = true;
var myMath = Object.assign({}, Math);

console.log(myMath.testProperty);