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));