手撕数组高阶函数

155 阅读2分钟

「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

前言

我们从数组最简单的遍历方法forEach说起,一步步地探索数组高阶函数的实现

1. Array.prototype.forEach()

var arr = ['a','b','c','d','e']
arr.forEach((currentValue,index,array)=>{
    console.log(currentValue);
    console.log(index);
    console.log(array);
})

-   "a"
-   0
-   ["a", "b", "c", "d", "e"]

-   "b"
-   1
-   ["a", "b", "c", "d", "e"]

-   "c"
-   2
-   ["a", "b", "c", "d", "e"]

-   "d"
-   3
-   ["a", "b", "c", "d", "e"]

-   "e"
-   4
-   ["a", "b", "c", "d", "e"]

forEach这个方法接收一个函数callback,调用callback,根据这个原理可以重写forEach方法

Array.prototype.forEachDemo = function(callback) {
    //1. 先判断'callback'是否为函数类型
    if (typeof callback !== "function") {
     throw new TypeError(callback + ' is not a function');
   }
   //2.循环调用callback()  this指向调用的arr
    for (var i = 0; i < this.length; i++) {
       callback(this[i],i,this)
   }
}

 var arr = ['aaa', 'bbb','ccc']
arr.forEachDemo((item,idx,arr) => {
   console.log(item,idx,arr)
})


-   "aaa"
-   0
-   ["aaa", "bbb", "ccc"]

-   "bbb"
-   1
-   ["aaa", "bbb", "ccc"]

-   "ccc"
-   2
-   ["aaa", "bbb", "ccc"]

这样一个简单的forEach函数就实现了

下面是更严谨的实现

Array.prototype.forEach1 = function(callback, thisArg) {

   var T, k;


   if (this == null) {
     throw new TypeError(' this is null or not defined');
   }
   var O = Object(this);
   // 3.将 len 转为整数
   var len = O.length >>> 0;
   // 4. 判断callback是否为函数
   if (typeof callback !== "function") {
     throw new TypeError(callback + ' is not a function');
   }
   // 5.如果传入 thisArg 将它赋给 T, 否则是T=undefined
   if (arguments.length > 1) {
     T = thisArg;
   }
   // 6. Let k be 0
   k = 0;
   // 7. 使用while循环
   while (k < len) {
     var kValue;
     if (k in O) {
       kValue = O[k];
       callback.call(T, kValue, k, O);
     }
     k++;
   }
 };

var arr = [1,2,3]
arr.forEach1(i => console.log(i))

-   1
-   2
-   3

以上就是数组forEach的实现方法

2. Array.prototype.map()

map的实现方法与forEach类似,只不过map会返回一个数组

 Array.prototype.mapDemo = function(callback) {
    //1. 先判断'callback'是否为函数类型
    if (typeof callback !== "function") {
     throw new TypeError(callback + ' is not a function');
   }
   // 2. 定义一个空数组
   var arr =[];
   //3循环调用callback()  this指向调用的arr
    for (var i = 0; i < this.length; i++) {
    //4.给arr中增加函数处理后的值
    arr.push(callback(this[i],i,this))
   }
   return arr;
}
 var arr = [1,2,3,4]
 
var addArr= arr.mapDemo(function(i) { return i+1;})
 console.log(addArr)  // [2, 3, 4, 5]