Array.prototype.myForEach = function (callback, thisArg) { // 判断调用该API的元素是否为null if (this == null) { throw new TypeError('this is null or not defined') } // 判断是否为function if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function') } // 通过this得到调用者arr const arr = this // 确定循环变量 let index = 0 // 循环遍历给每个数组元素调用callback while (index < arr.length) { // 判断是否存在这个项 if (index in arr) { // 通过call将this指向thisArg,并且传入3个参数 callback.call(thisArg, arr[index], index, arr) } index++ }}
Array.prototype.myMap = function (callback, thisArg) { // 和forEach相同需要进行两个排除 if (this == undefined) { throw new TypeError('this is null or not defined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } // 与forEach不同的是,map会返回一个新数组 const ret = [] // 获得函数调用者 const arr = this // 数组长度 let len = arr.length // 对每一个元素执行回调函数 for (let i = 0; i < len; i++) { // 检查i是否在arr if(i in arr) { ret[i] = callback.call(thisArg, arr[i], i, arr) } } // 返回一个处理后的数组 return ret}
Array.prototype.myFilter = function(callback,thisArg) { if (this == undefined) { throw new TypeError('this is null or not defined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } // 新数组 const res = [] // 保存this const arr = this // 提前计算数组长度 const len = arr.length for(let i = 0;i<len;i++) { if(i in arr) { // 判断元素经过函数调用后,是否有返回值 // 从而来判断是否满足筛选规则, if(callback.call(thisArg,arr[i],i,arr)) { res.push(arr[i]) } } } // 最后记得返回新数组噢 return res}
Array.prototype.mySome = function (callback, thisArg) { if (this == undefined) { throw new TypeError('this is null or not defined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } let arr = this let len = arr.length for (let i = 0; i < len; i++) { if (i in arr) { if (callback.call(thisArg, arr[i], i, arr)) { return true } } } return false}
Array.prototype.myEvery = function (callback, thisArg) { if (this == undefined) { throw new TypeError('this is null or not defined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } const arr = this const len = arr.length for (let i = 0; i < len; i++) { if (i in arr) { if (!callback.call(thisArg, arr[i], i, arr)) { return false } } } return true}
Array.prototype.myFind = function (callback, thisArg) { if (this == undefined) { throw new TypeError('this is null or not defined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } // 保存this,也就是调用者 const arr = this const len = arr.length for (let i = 0; i < len; i++) { if (i in arr) { if (callback.call(thisArg, arr[i], i, arr)) { return arr[i] } } } return undefined}
Array.prototype.myReduce = function (callback, initialValue) { // 判断调用该API的元素是否为null if (this == null) { throw new TypeError('this is null or not defined') } // 判断是否为function if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function') } const arr = this const len = arr.length // 第二个参数 let accumulator = initialValue let index = 0 // 如果第二个参数是undefined 则数组的第一个有效值 // 作为累加器的初始值 if (accumulator === undefined) { // 找到数组中的第一个有效值 不一定就是arr[0] while (index < len && !(index in arr)) { index++ } if (index >= len) { throw new TypeError('Reduce of empty array with no initial value') } // 输出第一个有效数组元素,作为累加器的第一个元素 accumulator = arr[index++] } while (index < len) { if (index in arr) { // arr[index] 为 accumulator 的下一个元素 accumulator = callback.call(undefined, accumulator, arr[index], index, arr) } // 持续后移 index++ } // 返回结果 return accumulator}
Array.prototype.mapReduce = function (callback, context = null) { if (this == null) { throw new TypeError('this is null or not defined') } // 判断是否为function if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function') } let arr = this return arr.reduce((pre, cur, index, array) => { let res = callback.call(context, cur, index, array) return [...pre, res] })}