高阶函数指的是至少满足下列条件之一的函数:
- 函数可以作为参数被传递
- 函数可以作为返回值输出
1.函数作为参数传递
把函数作为参数传递,这代表我们可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数参数中,这样一来可以分离业务代码中变化与不变的部分。其中一个重要应用场景就是常见的回调函数。以下是常见场景:
场景一:回调函数
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.userName ); });
回调函数应用不仅只在异步请求中,当一个函数不适合执行一些请求时,我们也可以把这些请求封装成一个函数,并把它作为参数传递给另一个函数,“委托“给另一个函数来执行
场景二:Array.prototype.sort
这是数组的排序API:
[2,4,1,6].sort( function(a,b){ return a-b }) // [1,2,4,6]
可以看到,sort中我们的目的是对数组进行排序,这是不变的部分;使用什么规则去排序,这是可变的部分。
[2,1,3].sort(function(a,b){ return a-b }) // [1,2,3] [2,1,3].sort(function(a,b){ return b-a }) // [3,2,1]
2.函数作为返回值输出
相比把函数作为参数传递,函数作为返回值输出的应用场景更多。让函数继续返回一个可执行的函数,意味着运算过程是可延续的。
例如一个判断对象是不是数组,可以把这个判断的代码提取到一个函数中,然后将其返回值作为判断的结果:
let isArr = function(obj){ return Object.prototype.toString.call(obj) === '[object Array]' } console.log(isArr([])); // true console.log(isArr({})); // false
3.AOP
AOP(面向切面编程):的主要作用是把一些跟核心业务逻辑模块无关的功能(日志统计、安全控制、异常处理等)抽离出来。然后再通过“动态织入”的方式掺入业务逻辑模块中。好处是可以保持业务逻辑模块的纯净和高内聚行,其次可以很方便的复用这些抽离的功能模块。
在JS中将一个函数“动态织入”到另一个函数中就是使用了JS中ES5的继承,即prototype来实现
4.高阶函数的其他应用
1.函数柯里化(function currying)
又称部分求值。一个柯里化函数首先会先接受一些参数,接收了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数中形成的闭包中被保存起来。待到函数被整整需要求值的时候,之前传入的所有参数都会被一次性用于求值。
let isArr = function(obj){
return Object.prototype.toString.call(obj) === '[object Array]'
}
console.log(isArr([])); // true
console.log(isArr({})); // false
未完待续。。。