javaScript高阶级函数

首先咱们须要知道什么是高级函数

  • 函数做为参数传递
  • 函数做为返回值输出

知足以上一个条件就能够称之为高阶级函数
java

函数做为参数传递

看一下例子
闭包

function iterator () {
     const obj = {
        message: '123'
        status: false
    }
    obj.status = true
    return obj
}
const obj2 = iterator()
console.log(obj2) // { message: '123', status: true }
复制代码

没毛病,but 问题来了,产品经理走过来和你提了一个需求,咱们要在iterator 外面作一些事情,这个事情作完以后再判断obj.status是要等于true仍是false。emmmmmm
app

好既然产品经理都这么说了。那咱们就开干吧。dom

function iterator (cb) {
     const obj = {
        message: '123'
        status: false
    }
    cb(obj)
    return obj
}
const obj2 = iterator((obj) => {
    console.log(obj2) // { message: '123', status: false }
    if (true) {
        obj.status = true
    } else {
        obj.status = false
    }
})
console.log(obj2) // { message: '123', status: true }
复制代码

👏👏👏👏 完成了一个产品经理的需求。函数当值传递,这是一个高级函数
其实咱们平时写的dom事件就是这样子方式,经过传入一个回调函数。函数

$('#btn').on('click', function() {
    $('#massage').show();
});
复制代码

传入了一个函数,当click监听到了信息,就会执行你传入的函数。
让咱们来个稍微高级点的。
ui

观察者模式this

class observer {
    constructor() {
        // 用来保存全部的事件
        this.obj = {}
    }
    emit (str) {
        // 发布一个事件
        const params = Array.prototype.slice.call(arguments, 1)
        this.obj[str] = (cb) => {
            cb(...params)
        }
    }
    on (str, fn) {
        // 执行一个事件
        this.obj[str](fn)
    }
}

const ob = new observer()
ob.emit('click', 1234, 'abcd')
ob.on('click', (a,b) => { 
    console.log(a,b) // 1234, 'abcd'
})
复制代码

没毛病,虽然这个代码缺少严谨,but 咱们只是为了展现一下搞基函数的方式之一函数当参数传递。
spa

函数做为返回值输出

function func () {
        let a = 1
        return function () {
            return a++
        }
    }
    let bb = func()
    cosnole.log(bb())
    cosnole.log(bb())
    cosnole.log(bb())
    cosnole.log(bb())
复制代码

相信你们对这个会打印啥都不陌生吧。prototype

//1 2 3 4
复制代码

每一个函数都是一个闭包,js访问一个变量是,会从自身做用域开始查找再慢慢向上查找,找到的第一个就取值。func这个函数 return 的这个function 没有a这个变量,因此就报错?no 可是它父亲有啊。它会向上找到后执行操做。最后外面js又发现全局变量bb引用了 这个function。因此js的自动垃圾回收机制放了这个a变量一马,没有回收它.
code

so 咱们再来个稍微高级点的。

节流

function debounce(fn, time) {
  // 记录当前执行函数状态
    let timer = null;
    let context = this;
    let args = arguments;
     return function() {
        if (timer) {
            // 任你滑,多执行一次算我输
            return false
        }
        timer = setTimeout(function() {
          clearTimeout(timer);
          timer = null
          fn.apply(context, args);
        }, time || 500);
      }
}
function foo() {
  console.log('你过来啊');
}

// 过 2 秒触发一次
window.addEventListener('scroll', debounce(foo, 2000));
复制代码

这是一个简单的节流函数,做用就是节流。卧槽这么粗暴的吗? 是的,我们是一篇讲解搞基函数的文章,说什么节流。要什么手表.
经过返回一个函数,咱们实现了,一个简单的节流函数。这是有同窗问,为啥那么复杂,咱们直接把timer变成一个全局变量不行吗?能够的。为啥不这样作你本身去想吧。知道了答案请留言。谢谢。

咱们的高级函数有不少玩法,好比柯理化和反柯理化。学无止境啊。