【问题标题】:Unexpected output from Object.assignObject.assign 的意外输出
【发布时间】:2019-03-21 13:38:39
【问题描述】:

所以我有点惊讶:

Object.assign({}, Math)

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

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

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

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

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

【问题讨论】:

    标签: javascript object ecmascript-6


    【解决方案1】:

    Math对象下的属性和方法设置为non-iterable。当Object.assign 试图复制它们时,它们不会出现。

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

    另一方面,Object.create 应该做你想做的事。

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

    【讨论】:

      【解决方案2】:

      发件人:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

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

      Math 属性不可枚举或拥有。

      例子:

      如何解决这个问题?

      使用Object.create 例如

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

      【讨论】:

      • 我相信 Math 属性是自己的(例如,Math.hasOwnProperty('abs') 是真的)。你是对的,它们是不可枚举的。
      • 如果是这种情况,那么像var myMath = Object.assign(Object.create(Math), {...myMethods}) 这样的东西应该可以工作。但它在我的控制台中不起作用。
      【解决方案3】:

      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 的行为,即赋值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-13
        • 2020-02-21
        • 2012-05-06
        • 2019-08-29
        • 2012-11-05
        • 2021-06-14
        • 2020-04-30
        • 1970-01-01
        相关资源
        最近更新 更多