在Object.assign()的MDN页面中,示例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(){})
)
让我们来分解一下:
测试对象是否存在,如果不存在则进行测试:
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');
}
将目标强制转换为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.
CCD_ 19以对象的形式为我们提供了有关属性的信息。
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
如果该属性未定义且可枚举,则将该属性设置为
to
的属性。
if (desc !== undefined && desc.enumerable) {
to[nextKey] = nextSource[nextKey];
}
}
}
return to;
}
});
}
最后返回带有新添加(克隆)属性的to
。