1. map
map方法与forEach方法均是对数组的遍历,不同的是map不操作原数组,而是返回一个新的数组
复制代码
/**
* __map
*
* @param {Function} callback
* @returns {Array}
*/
Array.prototype.__map = function(callback) {
var arr = []
for (var i = 0; i < this.length; i++) {
arr.push(callback.call(this, this[i], i, this))
}
return arr
}
var res = [1, 2, 3].__map(item => {
return item * 2
})
console.log('res: ', res);// res: [ 2, 4, 6 ]
//———————————————————————————MDN—————————————————————————————
// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.io/#x15.4.4.19
if (!Array.prototype.map) {
Array.prototype.map = function(callback/*, thisArg*/) {
var T, A, k;
if (this == null) {
throw new TypeError('this is null or not defined');
}
// 1. Let O be the result of calling ToObject passing the |this|
// value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal
// method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 1) {
T = arguments[1];
}
// 6. Let A be a new array created as if by the expression new Array(len)
// where Array is the standard built-in constructor with that name and
// len is the value of len.
A = new Array(len);
// 7. Let k be 0
k = 0;
// 8. Repeat, while k < len
while (k < len) {
var kValue, mappedValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal
// method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Let mappedValue be the result of calling the Call internal
// method of callback with T as the this value and argument
// list containing kValue, k, and O.
mappedValue = callback.call(T, kValue, k, O);
// iii. Call the DefineOwnProperty internal method of A with arguments
// Pk, Property Descriptor
// { Value: mappedValue,
// Writable: true,
// Enumerable: true,
// Configurable: true },
// and false.
// In browsers that support Object.defineProperty, use the following:
// Object.defineProperty(A, k, {
// value: mappedValue,
// writable: true,
// enumerable: true,
// configurable: true
// });
// For best browser support, use the following:
A[k] = mappedValue;
}
// d. Increase k by 1.
k++;
}
// 9. return A
return A;
};
}
2. forEach
forEach方法用于操作原数组,没有返回值
复制代码
/**
* __forEach
*
* @param {Function} callback
* @returns {Array}
*/
Array.prototype.__forEach = function(callback) {
for (var i = 0; i < this.length; i++) {
callback.call(this, this[i], i, this)
}
}
var arr = [1, 2, 3]
var res = arr.__forEach((item,index) => {
return arr[index] = item * 2
})
console.log('arr: ', arr); // arr: [ 2, 4, 6 ]
console.log('res: ', res); // res: undefined
//———————————————————————————MDN—————————————————————————————
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
// 1. Let O be the result of calling toObject() passing the
// |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get() internal
// method of O with the argument "length".
// 3. Let len be toUint32(lenValue).
var len = O.length >>> 0;
// 4. If isCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let
// T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty
// internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as
// the this value and argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
3. every
ever用于返回数组每一项都符合相应条件,全部符合返回true,否则返回false
复制代码
/**
* __every
*
* @param {Function} callback
* @returns {Array}
*/
Array.prototype.__every = function(callback) {
for (var i = 0; i < this.length; i++) {
if(!callback.call(this, this[i], i, this)){
return false
}
}
return true
}
var arr = [1, 2, 3]
var res = arr.__every((item,index) => {
return item > 0
})
console.log('res: ', res); // res: true
var res = arr.__every((item,index) => {
return item > 2
})
console.log('res: ', res); // res: false
//------------------------MDN-----------------------
if (!Array.prototype.every) {
Array.prototype.every = function(callbackfn, thisArg) {
'use strict';
var T, k;
if (this == null) {
throw new TypeError('this is null or not defined');
}
// 1. Let O be the result of calling ToObject passing the this
// value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method
// of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (typeof callbackfn !== 'function') {
throw new TypeError();
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let k be 0.
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal
// method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal method
// of O with argument Pk.
kValue = O[k];
// ii. Let testResult be the result of calling the Call internal method
// of callbackfn with T as the this value and argument list
// containing kValue, k, and O.
var testResult = callbackfn.call(T, kValue, k, O);
// iii. If ToBoolean(testResult) is false, return false.
if (!testResult) {
return false;
}
}
k++;
}
return true;
};
}
4. some
some与every相对应,即只要有一个满足条件即为true,均不满足即为false
复制代码
/**
* __some
*
* @param {Function} callback
* @returns {Array}
*/
Array.prototype.__some = function(callback) {
for (var i = 0; i < this.length; i++) {
if(callback.call(this, this[i], i, this)){
return true
}
}
return false
}
var arr = [1, 2, 3]
var res = arr.__some((item,index) => {
return item > 2
})
console.log('res: ', res); // res: true
var res = arr.__some((item,index) => {
return item > 3
})
console.log('res: ', res); // res: false
//-------------------------MDN--------------------------
// Production steps of ECMA-262, Edition 5, 15.4.4.17
// Reference: http://es5.github.io/#x15.4.4.17
if (!Array.prototype.some) {
Array.prototype.some = function(fun/*, thisArg*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.some called on null or undefined');
}
if (typeof fun !== 'function') {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t && fun.call(thisArg, t[i], i, t)) {
return true;
}
}
return false;
};
}
5.find
find用于返回数组中第一项符合条件的item,否则返回undefined
/**
* __find
*
* @param {Function} callback
* @returns {Array}
*/
Array.prototype.__find = function(callback) {
for (var i = 0; i < this.length; i++) {
if(callback.call(this, this[i], i, this)){
return this[i]
}
}
return undefined
}
var arr = [1, 2, 3]
var res = arr.__find((item,index) => {
return item > 1
})
console.log('res: ', res); // res: 2
var res = arr.__find((item,index) => {
return item > 2
})
console.log('res: ', res); // res: 3
6. findIndex
findIndex用户也是用于找到符合条件的item,不过返回的是item的下标,均不符合返回-1
/**
* __findIndex
*
* @param {Function} callback
* @returns {Array}
*/
Array.prototype.__findIndex = function(callback) {
for (var i = 0; i < this.length; i++) {
if(callback.call(this, this[i], i, this)){
return i
}
}
return -1
}
var arr = [1, 2, 3]
var res = arr.__findIndex((item,index) => {
return item > 1
})
console.log('res: ', res); // res: 1
var res = arr.__findIndex((item,index) => {
return item > 4
})
console.log('res: ', res); // res: -1
//--------------------------MDN-----------------------------
// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, 'findIndex', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return k.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return k;
}
// e. Increase k by 1.
k++;
}
// 7. Return -1.
return -1;
}
});
}