JavaScript高階函數

  • 2019 年 11 月 6 日
  • 筆記

至少滿足下列條件之一的函數

  • 可以作為參數被傳遞
  • 可以作為返回值輸出

應用場景

作為參數傳遞

回調函數

ajax 非同步請求完成之後執行

var getUserInfo = function( userId, callback ){     $.ajax( 'http://xxx.com/getUserInfo?' + userId, function( data ){         if ( typeof callback === 'function' ){             callback(data);         }     });  }  getUserInfo( 13157, function( data ){     console.log(data.userName);  });

Array.prototype.sort

//從小到大排列  [ 1, 4, 3 ].sort( function( a, b ){     return a - b;  });  // 輸出: [ 1, 3, 4 ]    //從大到小排列  [ 1, 4, 3 ].sort( function( a, b ){     return b - a;  });  // 輸出: [ 4, 3, 1 ]

作為返回值輸出

判斷數據的類型

var Type = {};  for (var i = 0, type; type = ['String', 'Number', 'Boolean', 'Object'][i++];) {     (function(type) {         Type["is" + type] = function(o) {             return Object.prototype.toString.call(o) === '[object ' + type + ']';         }     })(type);  }    console.log(Type.isString("hh"));

getSingle

單例模式的例子

var getSingle = function ( fn ) {     var ret;     return function () {         return ret || ( ret = fn.apply( this, arguments ) );     };  };  //效果  var getScript = getSingle(function(){  `return document.createElement( 'script' );  });  var script1 = getScript();  var script2 = getScript();  alert ( script1 === script2 ); // 輸出: true

實現AOP

把一些跟核心業務邏輯模組無關的功能抽離出來,這些跟業務邏輯無關的功能通常包括日誌統計、安全控制、異常處理等 可以保持業務邏輯模組的純凈和高內聚性

在 JavaScript中實現 AOP,都是指把一個函數「動態植入」到另外一個函數之中,例如擴展 Function.prototype

Function.prototype.before = function(beforeFn) {      var self = this;      return function() {          beforeFn.apply(this, Array.prototype.slice.call(arguments));          return self.apply(this, Array.prototype.slice.call(arguments));      }  };    Function.prototype.after = function(afterFn) {      var self = this;      return function() {          var ret;          ret = self.apply(this, Array.prototype.slice.call(arguments));          afterFn.apply(this, Array.prototype.slice.call(arguments));          return ret;      }  }    var func = function() {      console.log(2);  }  func = func.before(function() {      console.log(1);  }).after(function() {      console.log(3);  })  func();//1 2 3

柯里化

currying又稱部分求值。一個currying的函數首先會接受一些參數,接受了這些參數之後,該函數並不會立即求值,而是繼續返回另外一個函數,剛才傳入的參數在函數形成的閉包中被保存起來。待到函數被真正需要求值的時候,之前傳入的所有參數都會被一次性用於求值。

var curry = (function() {      var data = [1];      var func = function(n) {          data.push(n);          return func;      }      func.valueOf = function() {          var ret = data.reduce(function(a, b) {              return a * b;          })          data = [1];          return ret;      }      return func;  })();    console.log(curry(1));  console.log(curry(1)(2));  console.log(curry(1)(2)(3));

專門定義一個函數,對上面解法的參數進行柯里化⬇️

var curry = function(fn) {      var args = [];      var ret = function(n) {          args.push(n);          return ret;      }        ret.valueOf = function() {          var ret = args.reduce(fn);          args = [];          return ret;      }      return ret;  }    var func = curry(function(a, b) {      return a * b;  })    console.log(func(1));  console.log(func(1)(2));  console.log(func(1)(2)(3));