`Object.assign()`polyfill中`Object(target)`的目的是什么?

时间:2015-02-22 11:03:51

标签: javascript javascript-objects ecmascript-6 polyfills

MDN page forObject.assign()示例中,polyfill首先在Object()中包装所有源和目标参数,然后迭代属性。 (即Object(target)Object(source1)Object(source2) ...)。

该文本还提到在返回目标之前,会将其他属性直接添加到目标。但是,将目标包装在Object()中会导致对象与简单地扩充属性不同。 (即Object(target).newProp !== target.newProp)。

给出的所有示例都将对象作为Object.assign()的参数。因此,非对象源或目标参数的用例并不清楚。

A)Object()中包装参数的目的是什么? (我的印象是Object.keys(x)Object.keys(Object(x)))相同。

B)Object.assign()与非对象一起使用的可能用例是什么? (例如:Object.assign(1, 'b', [3], true, function(){})

1 个答案:

答案 0 :(得分:2)

让我们分解一下:

  

测试对象是否存在,如果不存在:

if (!Object.assign) {
  

通过Object.defineProperty制作方法并将其添加到Object

    Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
  

这里设置实际功能。一个人需要提供一个目标和一个最小来源。

    value: function(target, firstSource) {
      'use strict';
  

如果未定义目标则抛出错误。

      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }
  

将目标投射到对象格式。 (例如,字符串1234[object String]{0: "1", 1: "2", 2: "3", 3: "4", length: 4}

      var to = Object(target);
  

现在使用函数的arguments对象遍历所有源。从1开始,因为0是目标。

      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i]; //store the argument in a variable.
        if (nextSource === undefined || nextSource === null) {
          continue; //if the source is undefined continue. 
        }
  

然后我们需要来自源对象的所有(不仅是暴露的)可枚举属性,将Object.keysObject(source)结合使用。

        var keysArray = Object.keys(Object(nextSource));
  

迭代键:

        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex]; //select the key from the index.
  

getOwnPropertyDescriptor以对象的形式向我们提供有关该属性的信息。

          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
  

如果属性未定义且可枚举,则将此属性设置为to的属性。

          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

最后使用新添加的(克隆的)属性返回to