// 循環實現數組 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)