'use strict'; var aCallable = require('../internals/a-callable'); var toObject = require('../internals/to-object'); var IndexedObject = require('../internals/indexed-object'); var lengthOfArrayLike = require('../internals/length-of-array-like'); var $TypeError = TypeError; var REDUCE_EMPTY = 'Reduce of empty array with no initial value'; // `Array.prototype.{ reduce, reduceRight }` methods implementation var createMethod = function (IS_RIGHT) { return function (that, callbackfn, argumentsLength, memo) { var O = toObject(that); var self = IndexedObject(O); var length = lengthOfArrayLike(O); aCallable(callbackfn); if (length === 0 && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY); var index = IS_RIGHT ? length - 1 : 0; var i = IS_RIGHT ? -1 : 1; if (argumentsLength < 2) while (true) { if (index in self) { memo = self[index]; index += i; break; } index += i; if (IS_RIGHT ? index < 0 : length <= index) { throw new $TypeError(REDUCE_EMPTY); } } for (;IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) { memo = callbackfn(memo, self[index], index, O); } return memo; }; }; module.exports = { // `Array.prototype.reduce` method // https://tc39.es/ecma262/#sec-array.prototype.reduce left: createMethod(false), // `Array.prototype.reduceRight` method // https://tc39.es/ecma262/#sec-array.prototype.reduceright right: createMethod(true) };