polyfill
var reducePolyfill = function(callback) {
var k = [], key, t = this;
for(key in t) {
if (hasOwnProperty.call(t, key)) {
k.push(key);
}
}
var isArray = Object.prototype.toString.call(t) === '[object Array]';
var len = k.length >>> 0;
var argLen = arguments.length;
if (t === null) {
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
if (len === 0 && argLen === 1) {
throw new TypeError('Reduce of empty array with no initial value');
}
if (len === 1 && argLen === 1) {
return t.pop();
}
if (len === 0 && argLen === 2) {
return arguments[1];
}
var init, i;
if (argLen === 1) {
init = t[k[0]];
i = 1;
} else {
init = arguments[1];
i = 0;
}
for(;i<len;i++) {
init = callback(init, t[k[i]], k[i]);
}
return init;
};
Array.prototype.reduce = reducePolyfill;
Object.prototype.reduce = reducePolyfill;
console.log({a: 1, b: 2, c: 3}.reduce(function(res, val) {
res += val;
return res;
}, 0));
console.log({a: 1, b: 2, c: 3}.reduce(function(res, val, key) {
res += `${key}: ${val}\n`;
return res;
}, ''));
console.log([1, 2, 3].reduce(function(res, val) {
res += val;
return res;
}, 0));
console.log([1, 2, 3].reduce(function(res, val, key) {
res += `${key}: ${val}\n`;
return res;
}, ''));
console.log([1, 2, 3].reduce(function(res, val, key) {
res += val;
return res;
}));
console.log([1].reduce(function(res, val, key) {
res += val;
return res;
}));
console.log([].reduce(function(res, val, key) {
res += val;
return res;
}, 1));