Javascript 来自Object.assign的意外输出

Javascript 来自Object.assign的意外输出,javascript,object,ecmascript-6,Javascript,Object,Ecmascript 6,所以我有点惊讶于: Object.assign({}, Math) 返回了一个空对象。我这样做是为了建立自己的数学模块,我可以用自己的自定义功能进行扩展,因此我认为这样做会很方便: Object.assign({}, Math, { sqrt: <my-sqrt-implementation>, add: <my-add-implementation >, }) 出了什么问题,如何修复?来自: assign()方法仅将源对象的可枚举属性和自身属性复制到目标

所以我有点惊讶于:

Object.assign({}, Math)
返回了一个空对象。我这样做是为了建立自己的数学模块,我可以用自己的自定义功能进行扩展,因此我认为这样做会很方便:

Object.assign({}, Math, { 
  sqrt: <my-sqrt-implementation>, 
  add: <my-add-implementation >,
})
出了什么问题,如何修复?

来自:

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

Math
属性不可枚举或不属于自己

例如:

如何解决这个问题

使用
对象。创建
例如

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

Math
的属性不可用。将仅复制可枚举和自己的属性:

Object.assign()
方法仅将源对象的可枚举属性和自身属性复制到目标对象。它在源上使用
[[Get]]
,在目标上使用
[[Set]]]
,因此它将调用getter和setter。因此,它可以指定属性,而不仅仅是复制或定义新属性。如果合并源包含getter,则这可能不适合将新属性合并到原型中。用于将属性定义(包括其可枚举性)复制到原型
对象中。应改用getOwnPropertyDescriptor()
对象。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
尝试复制它们时,它们不会显示

如果您将自己的属性添加到
Math
对象,您将看到它被找到并复制了

对象。另一方面,创建
,应该执行您想要的操作

//你不应该真的这么做。
Math.testProperty=true;
var myMath=Object.assign({},Math);

log(myMath.testProperty)我相信数学属性是自己的(例如,Math.hasOwnProperty('abs')是真的)。如果是这种情况,那么像
var myMath=Object.assign(Object.create(Math),{…myMethods})
这样的方法应该可以工作。但它在我的控制台中不起作用。
const props = Object.getOwnPropertyNames(Math)
const myMath = {}
props.forEach(prop => {
    Object.defineProperty(myMath, prop, Object.getOwnPropertyDescriptor(Math, prop))
})

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