高阶函数

概念


1、一个函数的参数 是一个函数

1
2
3
4
function a(){
}
a( ()=>{})
// 函数a就是一个高阶函数

2、一个函数 返回一个函数

1
2
3
4
5
function a(){
return function (){
}
}
// 函数a就是一个高阶函数

简单应用


函数的before

需求:在“说话”之前要有其他的操作,可以直接在say函数中todo

1
2
3
4
5
6
const say = () => {
// console.log("张三");
// console.log("李四");
console.log('说话');
}
say();

现在希望将函数的核心部分提取出来 在外面增加功能

1
2
3
4
5
6
7
8
const say = () => {
console.log('说话');
}
const newSay = say.before( ()=>{
console.log("张三"); // todo
})
newSay();
// 在say方法之前加一个before方法,使其在调用say方法的时候 之前先调用before方法

在原型上添加before方法

1
2
3
4
5
6
7
Function.prototype.before = function(beforeFn){ // 函数的参数是函数  高阶函数
return () => { // 在函数中返回一个函数 高阶函数
beforeFn();
this(); // 箭头函数中没有this指向,所以会像上级作用域查找
// 这里面的this会向上级查找 调用这个before方法的是say 即这里执行say方法
}
}

合在一起如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Function.prototype.before = function(beforeFn){
return () => {
beforeFn();
this();
}
}
const say = () => {
console.log('说话');
}
const newSay = say.before( ()=>{
console.log("张三");
})
const newSay2 = say.before( ()=>{ // 示例 2
console.log("李四");
})
newSay(); // 结果: 张三 说话
newSay2(); // 结果:李四 说话

这就是AOP 面向切片编程 或者叫装饰 我们给say方法装饰了一些自己独特的逻辑 这个就是一个典型的高阶函数的使用。
AOP的思想:把核心抽离出来 在核心基础上增加功能。


拓展:添加参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Function.prototype.before = function(beforeFn){  
return (...args) => { // #1->
// 箭头函数中没有this指向 也没有arguments
// 所以在接受参数的时候可以先把所有的函数参数都接收到一起 ...arg
beforeFn();
this(...args); // 展开运算符 表示把所有的函数参数都展开
}
}
const say = (...args) => { // 剩余运算符 把所有的参数组成一个数组
console.log('说话', args);
}
const newSay = say.before( ()=>{
console.log("张三");
})
newSay(1,2,3);
// 打印结果:
// 张三
// 说话 [ 1, 2, 3 ]
//
// 疑问: newSay中的123怎么到箭头函数里去了#1->
// 这里newSay指的是 line2-line7这个return的返回值(函数),所以把参数传过去了