什么是高阶函数
高阶函数就是入参是函数或者返回值是函数的函数,如下所示:
function test(fn){
return function () {
fn()
}
}
我们常见的reduce函数就是一个高阶函数, 我们可以通过手写一个reduce函数来感受一下。
Array.prototype. reduce = function (fn,startVal) {
let i = typeof startVal === undefined? 1: 0;
let acc = typeof startVal===undefined? startVal: this[0];
while(i< this.length){
acc = fn(acc, this[i++])
}
return acc
}
函数作为参数的时候, 多数是对原有函数进行扩展 函数作为参数的并且返回值是函数的我们可以进行缓存
常见的高阶函数
切片函数
所谓的切片函数就是在原有函数的基础上,想再加入一些逻辑, 但是又不想改变原来的函数, 这个时候我们可以使用切片函数,可以看出切片函数就是对原有函数的扩展, 但是下面这种写法的话 , 会改变函数的原型链
function test () {
console.log("我要执行的")
}
Function.prototype.before (callback){
return function (...args) {
callback(...args)
this(...args)
}
}
let before = test.before(function () {
console.log("我想在之前执行有一些逻辑")
})
缓存函数
我们可以对函数的执行结果进行缓存,当第二次访问的时候就不需要再次执行, 一般换缓存的函数是纯函数。(所谓的纯函数, 就是针对每个输入有固定的输出), 下面我们来实现一个缓存函数, 这就是上面说的 , 如果同时作为参数和返回值的情况下, 一般是对函数结果进行缓存
function memorize (fn,resolver ){
let cache = new Map()
return function (...args) {
const key = typeof resolver=="function"? resolver(...args): args[0];
let result = Cache.get(key)
if(!result){
result = fn(...args)
Map.set(key, result)
}
return result
}
}
function resolver(...args){
return JSON.stringify(...args)
}
次数操作函数
比如我想执行几次之后再调用某个函数, 如果不想引入全局作用域, 我们可以依靠高阶函数来实现 , 内核其实还是闭包,如下面的代码所示:
function test () {
console.log("执行")}
function after(n, fn){
return function (...args) {
n--;
if(n===0){
fn(...args)
}
}
}