JavaScript implements the reduce() method function

I have problems to understand the code here.

  1. Why the index = intialArr.lenth - arr.length + 1;?
  2. How fn.call(null, arr[0], arr[1], index, initialArr); works.
    Emmm I know how call works but I kown how those parameter works.

1.code

Array.prototype.fakeReduce = function fakeReduce(fn, base) {

  let initialArr = this;
  let arr = initialArr.concat();

  if (base) arr.unshift(base);
  let index, newValue;

  while (arr.length > 1) {
    index = initialArr.length - arr.length + 1;
    newValue = fn.call(null, arr[0], arr[1], index, initialArr);

    arr.splice(0, 2, newValue); 
  }

  return newValue;
};

2.test

let arr = [1, 2, 3, 4, 5];
let sum = arr.fakeReduce((prev, cur, index, arr) => {
  console.log(prev, cur, index, arr);
  return prev * cur;
}, 100);

console.log(sum);

3.output

100 1 0 [ 1, 2, 3, 4, 5 ] 
100 2 1 [ 1, 2, 3, 4, 5 ] 
200 3 2 [ 1, 2, 3, 4, 5 ] 
600 4 3 [ 1, 2, 3, 4, 5 ] 
2400 5 4 [ 1, 2, 3, 4, 5 ] 
12000
Array.prototype.fakeReduce = function fakeReduce(fn, base) {

  let initialArr = this;
  let arr = initialArr.concat();

  if (base) arr.unshift(base);
  let index, newValue;

  while (arr.length > 1) {
    index = initialArr.length - arr.length + 1;
    newValue = fn.call(null, arr[0], arr[1], index, initialArr);

    arr.splice(0, 2, newValue); 
  }

  return newValue;
};
// Inputs to function:
fn == (prev, cur, index, arr) => prev * cur
base == 100

// value of `this`:
initialArr == [1, 2, 3, 4, 5]
// shallow copy of `this`:
arr == [1, 2, 3, 4, 5]

//  if (base) arr.unshift(base)
// NOTE above is bad code, as 0, false, "" should all be valid values for base
// base is not false, so unshift 100, updating `arr`
arr == [100, 1, 2, 3, 4, 5]

// set up index and newValue variables
index  = undefined
newValue = undefined

// while loop
// arr.length is 6, 6 > 1, so
index == 5 - 6 + 1 == 0;
newValue == fn.call(null, arr[0], arr[1], index, initialArr)
                == fn.call(null, 100, 1, 0, [1,2,3,4,5])
                == fn(100, 1)
                == 100
// arr.splice(0, 2, 100)
// removes the first two values (the previous and current in the reduce `fn`)
// and replaces with the new value
arr == [100, 2,3,4,5]

// arr.length is 5, 5 > 1, so
index == 5 - 5 + 1 == 1;
newValue == fn.call(null, arr[0], arr[1], index, initialArr)
                == fn.call(null, 100, 2, 1, [1,2,3,4,5])
                == fn(100, 2)
                == 200
// arr.splice(0, 2, 200)
// removes the first two values (the previous and current in the reduce `fn`)
// and replaces with the new value
arr == [200,3,4,5]

// arr.length is 4, 4 > 1, so
index == 5 - 4 + 1 == 2;
newValue == fn.call(null, arr[0], arr[1], index, initialArr)
                == fn.call(null, 200, 3, 2, [1,2,3,4,5])
                == fn(200, 3)
                == 600
// arr.splice(0, 2, 600)
// removes the first two values (the previous and current in the reduce `fn`)
// and replaces with the new value
arr == [600,4,5]



// arr.length is 3, 3 > 1, so
index == 5 - 3 + 1 == 3;
newValue == fn.call(null, arr[0], arr[1], index, initialArr)
                == fn.call(null, 600, 4, 3, [1,2,3,4,5])
                == fn(600, 4)
                == 2400
// arr.splice(0, 2, 2400)
// removes the first two values (the previous and current in the reduce `fn`)
// and replaces with the new value
arr == [2400,5]

// arr.length is 2, 2 > 1, so
index == 5 - 2 + 1 == 4;
newValue == fn.call(null, arr[0], arr[1], index, initialArr)
                == fn.call(null, 2400, 5, 4, [1,2,3,4,5])
                == fn(2400, 5)
                == 12000
// arr.splice(0, 2, 1200)
// removes the first two values (the previous and current in the reduce `fn`)
// and replaces with the new value
arr == [12000]

// arr.length is 1, 1 ! > 1, so
// return newValue
return 12000
2 Likes

Omg, This it’s an amazing answer. I just understand it simply…