JS高阶函数|青训营笔记

118 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第1天

什么是JS中的高阶函数

image.png 高阶函数(Higher-order function)简称HOF。他有一下三个特点

  1. 以函数作为参数
  2. 以函数作为返回值
  3. 常用于作为函数装饰器

代码格式

    function HOFO(fn){
        return function(...args){
            return fn.apply(this,args)
        }
    }

常见的高阶函数


Once()

该函数保证其包含的函数只执行一次,避免用户连续点击某一个控件而导致一直触发某一个事件

    function once(fn) {
      return function(...args) {
        if(fn) {
          const ret = fn.apply(this, args);
          fn = null;
          return ret;
        }
      }
    }

Throttle()

该函数为节流函数,如下例代码为例,设定时间500ms触发一次。无论点击频率多大,该函数都保证500ms触发一次,就比如在码上掘金上有自动保存并执行代码的功能

    function throttle(fn, time = 500){
      let timer;
      return function(...args){
        if(timer == null){
          fn.apply(this,  args);
          timer = setTimeout(() => {
            timer = null;
          }, time)
        }
      }
    }

Debounce()

该函数是一个防抖动的函数,常用场景:如下图,当鼠标一直在移动的时候,该小鸟不会跟随鼠标移动,而当一定的时间过去,鼠标没有移动的时候,小鸟才会跟随鼠标移动。

码上掘金有自动保存并执行代码的功能,但是当键盘一直在编辑时候,我们不希望编译器立马执行,而当你的键盘在一定时间内不再按下,再执行代码,所用的就是Debounce()函数

    function debounce(fn, dur){
      dur = dur || 100;
      var timer;
      return function(){
        clearTimeout(timer);
        timer = setTimeout(() => {
          fn.apply(this, arguments);
        }, dur);
      }
    }

image.png

Consumer()

将一个异步的事件变成同步的执行,我们可以设置一个timer,来确定我们的程序时隔timer的事件才会调用一次。如下面这个例子,我们设置timer为500ms,则我们连续点击hit10下,数字不会瞬间变成10,而是每隔500ms的事件执行一次,直到加到10。相当于一个延时的特性

    function consumer(fn, time){
      let tasks = [],
          timer;

      return function(...args){
        tasks.push(fn.bind(this, ...args));
        if(timer == null){
          timer = setInterval(() => {
            tasks.shift().call(this)
            if(tasks.length <= 0){
              clearInterval(timer);
              timer = null;
            }
          }, time)
        }
      }
    }

image.png

Iterative()

该函数是一个可迭代的高阶函数,在以往jQuery中运用广泛,可实现批量操作多个元素

    function iterative(fn) {
      return function(subject, ...rest) {
        if(isIterable(subject)) {
          const ret = [];
          for(let obj of subject) {
            ret.push(fn.apply(this, [obj, ...rest]));
          }
          return ret;
        }
        return fn.apply(this, [subject, ...rest]);
      }
    }

为什么我们需要高阶函数

高阶函数是纯函数(pure),它的结果是可预期的,它的输入了确定它的输出 非纯函数不容易测试,在一个库中,非纯函数越多,越不容易维护和扩展。所以我们要保证一个程序中有尽可能多的纯函数,减少非纯函数的个数。使用高阶函数,可以大大减少使用非纯函数的可能性。

结语

在本文中,我介绍了一些常用的高阶函数,在我们编程的过程中,逐渐提高我们的编程能力,多使用高阶函数,这样可以让我们的代码具有更多的扩展性和可维护性。