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