zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    搭建Git本地服务器
    shutdown,init,halt,poweroff,reboot的区别和联系, pkill -kill -t tty7注销
    RHEL/CentOS/Fedora常用的 CentOS 5/6/7 yum 源(EPEL、Remi、RPMForge、RPMFusion, ius,163,sohu,阿里云)配置
    国内的一些开源镜像站汇总,EPEL源
    EditPlus 配置 Java & C/CPP 开发环境
    Nginx+Keepalived 做负载均衡器
    监控Nginx负载均衡器脚本
    Heartbeat+DRBD+NFS 构建高可用的文件系统
    数据库索引的作用和长处缺点
    【ThinkPHP学习】ThinkPHP自己主动转义存储富文本编辑器内容导致读取出错
  • 原文地址:https://www.cnblogs.com/jett-woo/p/12693942.html
Copyright © 2011-2022 走看看