函数式编(一)——高阶函数

75 阅读2分钟

什么是高阶函数

高阶函数就是入参是函数或者返回值是函数的函数,如下所示:

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)
    }
     }
}