Skip to content

Instantly share code, notes, and snippets.

@sofish
Created October 8, 2012 05:16
Show Gist options
  • Save sofish/3850834 to your computer and use it in GitHub Desktop.
Save sofish/3850834 to your computer and use it in GitHub Desktop.
array 的 reduce 方法好奇怪
var arr = [1,2,3,4,5,6,7,8,9];
arr.reduce(function(prev, cur, i, index){
// 奇葩
console.log(prev,cur,i,index, arr[--i] === prev)
})
arr.reduce(function(prev, cur, i, index){
// 正常
console.log(prev,cur,i,index, arr[--i] === prev)
return cur;
})
@risent
Copy link

risent commented Oct 8, 2012

第一个reduce的callback没有返回值,相当于是undefined了

arr.reduce(function(prev, cur, i, index){
  // 奇葩
  console.log(prev,cur,i,index, arr[--i] === prev);
  return undefined;
})

从MDN上搬个reduce的实现

if (!Array.prototype.reduce) {
  Array.prototype.reduce = function reduce(accumulator){
    if (this===null || this===undefined) throw new TypeError("Object is null or undefined");
    var i = 0, l = this.length >> 0, curr;

    if(typeof accumulator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception."
      throw new TypeError("First argument is not callable");

    if(arguments.length < 2) {
      if (l === 0) throw new TypeError("Array length is 0 and no second argument");
      curr = this[0];
      i = 1; // start accumulating at the second element
    }
    else
      curr = arguments[1];

    while (i < l) {
      if(i in this) curr = accumulator.call(undefined, curr, this[i], i, this);
      ++i;
    }

    return curr;
  };
}

第一次while循环的时候curr=this0,所以输出结果中获取到的prev就是数组的第一个元素, 而后所有循环的prev都是前一次调用callback的返回值, 而第一个arr.reduce中的callback没有返回值,所以就全都是undefiend。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment