高阶函数
一个函数接收另一个函数作为参数,这种函数就被称为高阶函数。常见的高阶函数有: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
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
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
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
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
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
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
2
3
4
5
6
7
8
9
10