高阶函数是至少满足下列条件之一的函数
  
函数作为参数传递
把函数当作参数传递,可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数中,可以分离业务代码中变与不变的部分。
- 回调函数,ajax异步,callback
1 2 3 4 5 6 7 8 9 10
   | var getUserInfo() = function(userId, callback) {     $.ajax('http://xxx.com/getUserInfo?' + userId, function(data) {         if (typeof(callback === 'function') {             callback(data);         }     }); } getUserInfo(13157, function(data) {     alert(data.user); })
  | 
 
高阶函数实现AOP
AOP(面向切面编程),把一些跟核心业务逻辑模块无关的功能抽离出来(通常包括日志统计,安全控制,异常处理等)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
   | Function.prototype.before = function(beforefn) {     var __self = this;      return function() {          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 ;     } };
  var func = function() {     console.log(2); };
  func = func.before(function() {     console.log(1); }).after(function() {     console.log(3); });
  func();
  | 
 
以上代码我们把打印1和打印3的函数通过AOP的方式动态植入func函数,于是执行时候顺利返回1,2,3
函数节流
js函数大多是用户触发,大多不会遇到跟性能相关的问题,但是少数情况触发不被用户控制的。
例如:
window.onresize事件
 
mousemove事件
 
上传进度
 
以上函数触发频率太高,比如我们对onresize事件绑定了打印事件,当拖动窗口时,可能会一秒打印十次,这太累了,因此要采取一点措施(聪明的机智的你一定想到了setTimeout)
主要实现原理:当即将被执行的函数用setTimeout延迟一段时间执行,如果这次延迟执行还没完成,则忽略接下来调用该函数的请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | var throttle = function(fn, interval) {     var __self = fn,      timer,      firstTime = true;      return function() {         var args = arguments,         __me = this;              if (firstTime) {              __self.apply(_me, args);             return firstTime = false;         }                  if (timer) {              return false;         }
          timer = setTimeout( function () {             clearTimeout(timer);             timer = null;             __self.apply(__me, args);         }, interval || 500);     }; };
  window.onresize = throttle(function() {     console.log(1); }, 500);
 
  |