在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(){})
)
答案 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.keys
与Object(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
。