提前为此篇文章的长度道歉。我想理解MDN提供的数组reduce polyfill(填充)的一些技术细节,但我无法理解polyfill中的某些代码行,请问能否给予解释?以下是相关代码:
if (!Array.prototype.reduce) {
Object.defineProperty(Array.prototype, 'reduce', {
value: function(callback /*, initialValue*/) {
if (this === null) {
throw new TypeError( 'Array.prototype.reduce ' +
'called on null or undefined' );
}
if (typeof callback !== 'function') {
throw new TypeError( callback +
' is not a function');
}
// 1. Let O be ? ToObject(this value).
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// Steps 3, 4, 5, 6, 7
var k = 0;
var value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < len && !(k in o)) {
k++;
}
// 3. If len is 0 and initialValue is not present,
// throw a TypeError exception.
if (k >= len) {
throw new TypeError( 'Reduce of empty array ' +
'with no initial value' );
}
value = o[k++];
}
// 8. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kPresent be ? HasProperty(O, Pk).
// c. If kPresent is true, then
// i. Let kValue be ? Get(O, Pk).
// ii. Let accumulator be ? Call(
// callbackfn, undefined,
// « accumulator, kValue, k, O »).
if (k in o) {
value = callback(value, o[k], k, o);
}
// d. Increase k by 1.
k++;
}
// 9. Return accumulator.
return value;
}
});
}
问题1:如果您看到步骤1,
var o = Object(this);
我已经通过向polyfill方法传递一个数组来检查o和this的两个值。 o和this没有任何区别。它们都是具有相同数组值的数组(array.isarray在两者上都返回true)。为什么不使用以下方式..?
var o = this;
问题2:第二步
var len = o.length >>> 0;
以上代码似乎将o.length(32位)右移了。然而,移动的位数为0。那么我们通过移动0个比特位得到什么优势呢?为什么不改用以下代码呢?
var len = o.length;
问题3:else语句内的第一个while条件如下
while (k < len && !(k in o)) {
k++;
}
一开始k被设置为0,它似乎总是存在于o中。因此,这个while循环条件永远不会成立。那么,如果它从未进入,我们为什么需要这个while循环。
arr = new Array(700000)
,然后arr[1] = someValue
。这样,0 in arr
将会是false
,但1 in arr
将会是true
,所以在这种情况下你仍然会得到k > 0
。 - Explosion Pillsvar arr = []; Object(arr) === arr;
)。如果它是一个原生值,例如字符串、数字等,则将其转换为String
、Number
等实例。如果它是undefined
,则转换为空对象。 - ibrahim mahrirundefined
。我已经编辑了答案来解释为什么。因为出现了无法访问未定义的属性 ****
的错误。 - ibrahim mahrirwhile
循环仅在我们使用没有 初始值 的reduce
调用时使用。然后,该循环从数组中获取第一个值并将其用作初始值。它使用与第二个while
循环相同的概念,该概念在上面的 问题3 部分中有解释。它只忽略不存在的索引。 - ibrahim mahrir