高阶函数 一个函数接收另一个函数作为参数,这种函数就被称为高阶函数。常见的高阶函数有:map/reduce、filter、sort、Array类的every、find、findIndex、forEach

1、ES5实现数组map方法

const map=function(fn,context){
    //拷贝
    let arr=[].slice.call(this);
    let mapArr=[];
    for(let i=0;len<arr.length;i<len;i++){
        if(arr.hasOwnProperty(arr[i])){
            mapArr.push(fn.call(context,arr[i],i,this))
        }
    }
    return mapArr;
}
1
2
3
4
5
6
7
8
9
10
11

2、使用reduce实现map

const map=function(fn,context){
    let arr=[].slice.call(this);
    return arr.reduce((pre,cur,index)=>{
        return [..prv,fn.call(context,cur,index,this)]
    },[])
}
1
2
3
4
5
6

3、ES5实现数据filter方法

const filter=function(){
    let arr=[].slice.call(this);
    let filterArr=[];
    for(let i=0,len=arr.length;i<len;i++){
        if(arr.hasOwnProperty(arr[i])){
            fn.call(context,arr[i],i,this)&&filterArr.push(arr[i]);
        }
    }
    return filterArr;
}
1
2
3
4
5
6
7
8
9
10

4、使用reduce实现filter方法

const filter=function(fn,context){
    return this.reduce((pre,cur,index)=>{
        fn.call(context,cur,index,this)[...pre,cur]:[...pre]
    },[])
}
1
2
3
4
5

5、ES5实现some方法

//空数组some方法直接返回false,而every返回true
const some=function(fn,context){
    let arr=[].slice.call(this);
    if(arr.length>0){
        for(let i=0,len=arr.length;i<len;i++){
            if(arr.hasOwnProperty(arr[i])){
                if(fn.call(context,arr[i],i,this)){
                    return true;
                }
            }
        }
        //走到这一步意味着前面没有调用return 
        return false;
    }else{
        return false;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

6、ES5实现数组的reduce方法

//简化版
Array.prototype.reduce=function(fn,initValue){
    const arr=[].slice.call(this);
    let res=arr[0];
    let startIndex=1;
    const len=arr.length;
    if(typeof initValue!=='undefined'){
        res=initValue;
        startIndex=0
    }
    for(let i=startIndex;i<len;i++){
       res= fn.call(arr,res,arr[i],i,this);
    }
    return res;
}
//进阶版
const reduce=function(fn,initValue){
    const arr=[].slice.call(this);
    let res=arr[0];
    let startIndex=1;
    const len=arr.length;
    if(typeof initValue==='undefined'){
        //保证跳过稀疏数组
        for(let i=0;i<len;i++){
            if(arr.hasOwnProperty(arr[i])){
                startIndex=i;
                res=arr[i];
                break;
            }
        }
    }else{
        startIndex=0;
        res=initValue;
    }
    for(let i=startIndex+1;i<len;i++){
        if(arr.hasOwnProperty(arr[i])){
            res=fn.call(null,res,arr[i],i,this);
        }
    }
    return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

7、使用reduce实现flat方法

    const flat=function(depth=1){
        let arr=[].slice.call(this);
        if(depth===0){
            return arr;
        }
        //后面的[...pre,cur]将前面的pre取代,这里是return的返回值将pre取代
        return arr.reduce((pre,cur)=>{
            return  Array.isArray(cur)?[...pre,...flat.call(cur,depth-1)]:[...pre,cur]
        },[])
    }
1
2
3
4
5
6
7
8
9
10
Last Updated: 10/18/2020, 11:59:20 PM