// 循环实现数组 filter 方法 const selfFilter = function (fn, context){ // 如果调用的地方使用箭头函数,这里的this岂不是不对了,那该怎么解决呢 let arr = Array.prototype.slice.call(this) let filterArr = [] for(let i = 0; i < arr.length; i++){ if(!arr.hasOwnProperty(i)){ continue } fn.call(context, arr[i], i, this) && filterArr.push(arr[i]) } return filterArr } const selfFilter2 = function (fn, context){ return this.reduce((pre, cur, index) => { // 因为这里是return 的,所以不能像上面用&&实现 return fn.call(context, cur, index, this) ? [...pre, cur] : [...pre] }, []) } // 循环实现数组的 some 方法 const selfSome = function (fn, context){ let arr = Array.prototype.slice.call(this) if(arr.length === 0){ return false } for(let i = 0; i < arr.length; i++){ if(!arr.hasOwnProperty(i)){ continue } let res = fn.call(context, arr[i], i, this) if(res){ return true } } return false } // 循环实现数组的 reduce 方法 const selfReduce = function (fn, initialValue){ let arr = Array.prototype.slice.call(this) let res let startIndex if(initialValue === undefined){ // 找到第一个非空单位(真实)的元素和下标 for(let i = 0; i < arr.length; i++){ if(!arr.hasOwnProperty(i)){ continue } startIndex = i res = arr[i] break } }else{ res = initialValue } for(let i = ++startIndex || 0; i < arr.length; i++){ if(!arr.hasOwnProperty(i)){ continue } res = fn.call(null, res, arr[i], i, this) } return res } // 使用 reduce 实现数组的 flat 方法 // flat()方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。 // 参数depth(可选),指定要提取嵌套数组的结构深度,默认值为1 const selfFlat = function (depth = 1){ let arr = Array.prototype.slice.call(this) if(depth === 0){ return arr } return arr.reduce((pre, cur) => { //[]我之前记忆错了,这个应该是全部都是值,比如[cur],如果是数组的话,应该要先解构,比如[...pre] // 我之前一直是用的[...pre],却忘记了原本的用处,记录一波 return Array.isArray(cur) ? [...pre, ...selfFlat.call(cur, depth - 1)] : [...pre, cur] }, []) } let arr1 = [1, 2, 3, 4] let arr2 = [1, 2, 3, [1, 5, 6, [2, 4, 5]]] // 看到上面方法的实现,我才想起,这些方法也可以用call来调用,call第一位 let arrList = selfFilter.call(arr1, function(x){ return x === 1 }) let arrList2 = selfFilter2.call(arr1, function(x){ return x === 1 }) let arrList3 = selfSome.call(arr1, function(x){ return x === 0 }) let arrList4 = selfReduce.call(arr1, function(total, res){ return total + res }, 0) let arrList5 = selfFlat.call(arr2, Infinity) console.log(arrList) console.log(arrList2) console.log(arrList3) console.log(arrList4) console.log(arrList5)