JS高阶函数

高阶函数

高阶函数是指满足下列条件之一的函数:

  1. 函数可以作为参数被传递
  2. 函数可以作为返回值输出

常见内置高阶函数

ES6新增的数组方法:map/reduce, fliter, sort排序等

高阶函数其他应用场景

  • 高阶函数实现AOP

  AOP面向切面编程:主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些无关模块通常包括日志统计,安全控制,异常处理等,然后再将这些支撑模块“动态织入”到另一个函数中去;java中通常是使用反射和动态代理模式来实现AOP,而js中可以很方便的利用高阶函数实现AOP编程

Function.prototype.before = function (beforeFn) {
  //假设调用的时候一般是fna.before(fnb);则这里的this是fna
  var self = this
  return function () {
    // 这里的this是装饰之后的函数调用的上下文,例子上f(3)调用时,没有显式的上下文,因此此时是window
    // console.log('inner:', this);
    // arguments即真正调用的时候传入的参数,此时beforeFn与self传入的是同一个参数,在例子中就是3
    beforeFn.apply(this, arguments)
    return self.apply(this, arguments)
  }
};

Function.prototype.after = function (afterFn) {
  var self = this

  return function () {
      var ret = self.apply(this, arguments)
      afterFn.apply(this, arguments)
      return ret
  }
}

function fna (a) {
  console.log(1+a)
}
function fnb (a) {
  console.log(2+a)
}
var f = fna.before(fnb)
f(3)
View Code
  • 函数柯里化(currying)

  函数柯里化curring又称为部分求值,一个currying的函数会先接受一些参数,接收了这些参数以后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存,待函数真正需要求值的时候,之前传入的所有参数都会被一次性的用于求值。

var currying = function (fn) {
  var args = []
  return function () {
    if (arguments.length >= 1) {
      [].push.apply(args, arguments) // 用来存储前几次调用传入的参数
      //其实这里有没有返回值不是必须的
      //return arguments.callee
    } else {
      return fn.apply(this, args)
    }
  }
}

function cost () {
  var money = 0
  for (var i=0; i<arguments.length; i++) {
      money += arguments[i]
  }
  console.log(money)
  return money
}

var cost = currying(cost)
cost(200, 300) //未真正求值
cost(400) //未真正求值
cost() //进行真正求值
View Code
  • 函数节流

  针对一些被频繁调用的函数,如onresize, mousemove等,它们共同的特征是函数被触发的频率太高了,事实上可能并不需要以这么高的频率调用

var throttle = function (callback, interval = 1000) {
  let timer
  let firstTime = true
  return function () {
    if (firstTime) {
      // 第一次不延迟执行
      callback.apply(this, arguments)
    }
    if (timer) {
      return false
    }

    timer = setTimeout(function () {
      // 清除定时器
      clearTimeout(timer)
      timer = null
      fn.apply(this, arguments)
    }, interval)
  }
}
View Code
  • 分时函数

  页面短时间内进行大量的DOM操作会造成页面卡主的情况,要循环在页面上新增1000个DOM节点,一种解决方案是下面的timeChunk函数,让原本1s钟创建1000个节点的操作,改为每200ms创建8个节点

var timeChunk = function (ary, fn, count) {
  var timer
  return function () {
    var operation = function () {
      for (var i = 0; i < Math.min(count || 1, ary.length); i++) {
        var curData = ary.shift()
        fn(curData)
      }
    }
    timer = setInterval(function () {
      if (ary.length <= 0) {
        clearInterval(timer)
        timer = null
        return
      }
      operation()
    }, 200)
  }
}
View Code

 

参考:https://www.cnblogs.com/FineDay/p/10238073.html

posted @ 2020-04-13 21:06  JettWoo  阅读(232)  评论(0编辑  收藏  举报