if (!Array.prototype.every) { Object.defineProperty(Array.prototype, 'every', { enumerable: false, value: function (callback) { if (this === null) { thrownewTypeError( 'Array.prototype.every ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError(callback + ' is not a function'); } let res = true; for (let [i, v] ofthis.entries()) { if (!callback(v)) { res = false; break; } } return res; }, }); }
if(!Array.prototype.some){ Object.defineProperty(Array.prototype, 'some', { enumerable: false, value: function (callbakc) { if (this === null) { thrownewTypeError( 'Array.prototype.some ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError(callback + ' is not a function'); } let res = false; for (let [i, v] ofthis.entries()) { if (callbakc(v, i, this)) { res = true; break; } } return res; }, }); }
if (!Array.prototype.filter) { Object.defineProperty(Array.prototype, 'filter', { enumerable: false, value: function (callback) { if (this === null) { thrownewTypeError( 'Array.prototype.filter ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError(callback + ' is not a function'); } let res = []; for (let i = 0; i < this.length; i++) { if (callback(this[i])) { res.push(this[i]); } } return res; }, }); }
if (!Array.prototype.find) { Object.defineProperty(Array.prototype, 'find', { enumerable: false, value: function (callback) { if (this === null) { thrownewTypeError( 'Array.prototype.find ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError(callback + ' is not a function'); } let res = undefined; for (let i = 0; i < this.length; i++) { if (callback(this[i], i, this)) { res = this[i]; break; } } return res; }, }); }
if (!Array.prototype.findIndex) { Object.defineProperty(Array.prototype, 'findIndex', { enumerable: false, value: function (callback) { if (this === null) { thrownewTypeError( 'Array.prototype.findIndex ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError(callback + ' is not a function'); } let res = -1; for (let i = 0; i < this.length; i++) { if (callback(this[i], i, this)) { res = i; break; } } return res; }, }); }
if (!Array.prototype.forEach) { Object.defineProperty(Array.prototype, 'forEach', { enumerable: false, value: function (callback) { if (this === null) { thrownewTypeError( 'Array.prototype.forEach ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError(callback + ' is not a function'); } for (let i = 0; i < this.length; i++) { callback(this[i], i, this); } }, }); }
if (!Array.prototype.map) { Object.defineProperty(Array.prototype, 'map', { enumerable: false, value: function (callback) { if (this === null) { thrownewTypeError( 'Array.prototype.map ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError(callback + ' is not a function'); } let res = []; for (let i = 0; i < this.length; i++) { res.push(callback(this[i], i, this)); } return res; }, }); }
// Production steps of ECMA-262, Edition 5, 15.4.4.21 // Reference: http://es5.github.io/#x15.4.4.21 // https://tc39.github.io/ecma262/#sec-array.prototype.reduce if (!Array.prototype.reduce) { Object.defineProperty(Array.prototype, 'reduce', { value: function(callback /*, initialValue*/) { if (this === null) { thrownewTypeError( 'Array.prototype.reduce ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError( callback + ' is not a function'); }
// 1. Let O be ? ToObject(this value). var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")). var len = o.length >>> 0;
// Steps 3, 4, 5, 6, 7 var k = 0; var value;
if (arguments.length >= 2) { value = arguments[1]; } else { while (k < len && !(k in o)) { k++; }
// 3. If len is 0 and initialValue is not present, // throw a TypeError exception. if (k >= len) { thrownewTypeError( 'Reduce of empty array ' + 'with no initial value' ); } value = o[k++]; }
// 8. Repeat, while k < len while (k < len) { // a. Let Pk be ! ToString(k). // b. Let kPresent be ? HasProperty(O, Pk). // c. If kPresent is true, then // i. Let kValue be ? Get(O, Pk). // ii. Let accumulator be ? Call( // callbackfn, undefined, // « accumulator, kValue, k, O »). if (k in o) { value = callback(value, o[k], k, o); }
//concise method if (!Array.prototype.reduce) { Object.defineProperty(Array.prototype, 'reduce', { enumerable: false, value: function (callback) { if (this === null) { thrownewTypeError( 'Array.prototype.map ' + 'called on null or undefined' ); } if (typeof callback !== 'function') { thrownewTypeError(callback + ' is not a function'); } let count = 0; for (let i = 0; i < this.length; i++) { count += callback(count, this[i], i, this); } }, }); }
var sum = [0, 1, 2, 3].reduceRight(function(a, b) { return a + b; }); // sum is 6 (虽然结果相同,但是是从右到左加)
展示 reduce 与 reduceRight 之间的区别
1 2 3 4 5 6
var a = ['1', '2', '3', '4', '5']; var left = a.reduce(function(prev, cur) { return prev + cur; }); var right = a.reduceRight(function(prev, cur) { return prev + cur; });
// Production steps of ECMA-262, Edition 5, 15.4.4.22 // Reference: http://es5.github.io/#x15.4.4.22 if ('function' !== typeofArray.prototype.reduceRight) { Array.prototype.reduceRight = function(callback /*, initialValue*/) { 'use strict'; if (null === this || 'undefined' === typeofthis) { thrownewTypeError('Array.prototype.reduceRight called on null or undefined'); } if ('function' !== typeof callback) { thrownewTypeError(callback + ' is not a function'); } var t = Object(this), len = t.length >>> 0, k = len - 1, value; if (arguments.length >= 2) { value = arguments[1]; } else { while (k >= 0 && !(k in t)) { k--; } if (k < 0) { thrownewTypeError('reduceRight of empty array with no initial value'); } value = t[k--]; } for (; k >= 0; k--) { if (k in t) { value = callback(value, t[k], k, t); } } return value; }; }
// array like object var obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.values(obj)); // ['a', 'b', 'c']
// array like object with random key ordering // when we use numeric keys, the value returned in a numerical order according to the keys var an_obj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.values(an_obj)); // ['b', 'c', 'a']
// getFoo is property which isn't enumerable var my_obj = Object.create({}, { getFoo: { value: function() { returnthis.foo; } } }); my_obj.foo = 'bar'; console.log(Object.values(my_obj)); // ['bar']
// non-object argument will be coerced to an object console.log(Object.values('foo')); // ['f', 'o', 'o']