MDN背后的逻辑减少了()pollyfill的循环

时间:2015-10-23 19:09:31

标签: javascript arrays

Array.prototype.reduce = function(callback /*, initialValue*/) { 'use strict'; var t = this, len = t.length, k = 0, value; //IF initial value provided - go to the for loop if (arguments.length == 2) { value = arguments[1]; } else { while (k < len && !(k in t)) { k++; } //IF no values then THROW a TYPEERROR if (k >= len) { throw new TypeError('Reduce of empty array with no initial value'); } value = t[k++]; } for (; k < len; k++) { if (k in t) { value = callback(value, t[k], k, t); } } return value; }; polyfill from MDN

else

问题:

  1. 脚本的while ... t部分是做什么的?它背后的逻辑是什么?我认为这与提供额外的初始值参数有关。但是for这里是数组上下文而不是方法的参数上下文。它似乎与(k in t)循环做同样的工作。

  2. 这里else { while (k < len && !(k in t)) { k++; } if (...) { ... } value = t[k++]; } 表达式的逻辑是什么?为什么要根据实际数组值检查迭代器值?

    {{1}}

1 个答案:

答案 0 :(得分:2)

第1部分找到有效现有初始值(如果尚未提供)。在稀疏数组中,您不能只假设array[0]已设置。

如果我们声明:

var sparse = [];
sparse[1] = "something";
sparse[4] = "else";

然后sparse[0]不是真正的值,并且不会是in sparse

您需要找到实际设置的第一个值。第一个索引是in数组。

所以,从k == 0开始:

while (k < len && !(k in t)) {
  k++; 
}

我们查看数组直到找到一个“真实”的索引。在我们的示例中,这将是sparse[1]

如果我们找不到,则下一个if会抛出错误。

否则,

value = t[k++];

我们有初始值,继续前进。

第2部分循环遍历数组的其余实际元素,为每个元素调用回调,并跳过“缺失”索引:

for (; k < len; k++) {
  if (k in t) {            
    value = callback(value, t[k], k, t);
  }
}

在我们的示例中,我们会跳过23,接下来我们会调用sparse[4]的回调。

如果数组不稀疏(例如var arr = [1,2,3,4];),这一切都正常,它就不会跳过任何内容。