高阶函数
什么是高阶函数
简单来说,高阶函数就是操作函数的函数;一般情况,在项目中都会分两种情况
- 函数可以作为参数传递到另一个函数
- 函数可以作为返回值输出不执行
第一种模式,函数作为参数传递到另一个函数
在业务代码中经常会遇到另个函数逻辑相同但业务逻辑不通的情况,我们可以把这两个相同逻辑封装成一个高阶代码,从而把不同的逻辑写在函数里面作为参数传递到封装好的函数里面。这样可以实现业务逻辑的一些变化,一些不变的场景,这种是我们最常见的场景,回调函数。
例子
两个不同的函数,有共同的逻辑部分,也有不同的逻辑部分
function a(){
console.log("我是一个函数")
console.log("我是a函数")
}
function b(){
console.log("我是一个函数")
console.log("我是b函数")
}
a()
b()
执行的结果
接下来,我们对这两个函数做下一步的处理
function c(fn){
console.log(“我是一个函数”)
fn()
}
c(function(){console.log("我是a函数")})
c(function(){console.log("我是b函数")})
我们将上述封装成一个高阶函数,相同的部分在该函数中,不同的部分作为参数传入
上述执行的结果是一样的
例子二
其实我们在项目中,还有一种场景,我们也经常用到高阶函数,我们经常会在项目中使用ajax或者axios请求等等一些异步操作,一般,往往我们不关心请求过程,请求的过程是相同的,我们只想要请求的结果处理不同的业务逻辑,我们可以利用高阶函数统一封装,也叫请求拦截
var httpsAjax = function(obj,callback){
var {url,data,type} = obj;
$.ajax({
url:url,
type:type || 'POST' ,
data:dara || {},
success:function(res){
//利用typeof 判断数据类型,如果是传进来的是函数,我们就执行回调函数
if(typeof callback === 'function'){
callback(res)
}
}
})
}
httpsAjax({ url:"xxx/get/user", type:"GET", data:{} },function(res){ //操作一定的业务逻辑 console.log(res) })
从上面的示例中,我们可以知道,我们在项目已经用到过高阶函数,将函数作为回调函数传给另一个函数调用。
第二种模式,作为返回值输出
相比把函数作为参数传递给函数,函数作为函数返回值的应用场景也很多,让函数继续返回一个可执行的函数,这样意味着运算过程是可延续的,就比如我们用到数组的排序方法 Array.prototype.sort
下面是试用Object.prototype.toString方法判断数据类型的isType函数的例子
var isString = function(obj){
return Object.prototype.toString.call(obj) === '[object String]'
}
var isArray = function(obj){
return Object.prototype.toString.call(obj) === '[object Array]'
}
var isNumber = function(obj){
return Object.prototype.toString.call(obj) === '[object Number]'
}
var is_type = function(obj,type){
return Object.prototype.toString.call(obj) === '[object '+ type + ']'
}
console.log(is_type(11,'Number'))
在上述代码中,我们可以发现相同的逻辑 我们去判断传入参数的类型都是调用了Object.prototype.toString.call()
来实现的,不同的是处理返回字符串的结果,为了避免冗余,我们将代码封装成is_type
函数,我们从is_type函数中可以发现,代码量变少了,但是需要传递两个参数,而且传递的参数需要一一对应,如果没有对应上,可能会出现bug,因此我们在做进一步的封装,将其封装成高阶函数
var is_Type = function(type){
return function(obj){
return object.prototype.toString.call(obj) === '[object ' + type + ']'
}
}
var isString = is_Type('String')
console.log(isString('111'))
var isArray = is_Type('Array')
console.log(isArray([1,2,3]))
var isNumber = is_Type('Number')
console.log(isNumber(11))
从上面的例子中,我们可以看出第二种模式是让一个函数返回另一个函数,让函数的运算延续下去
JavaScript中经常用到的高阶函数
- map
- sort
- filter
- reduce
map
定义:map方法就是遍历原有数组返回新数组,数组中的元素为原始数组元素调用函数处理的值,按照原始数组原始顺序依次处理元素
注意:不会对空数组进行检索,返回的是新数组,不会改变原始数组的值
语法格式
newArray.map(function(item){
//遍历newArray item是newArray元素;类似于newArray[i] return item //必须有return,反正不会产生新的数组
})
map方法定义在JavaScript的Array中,我们调用Array的map方法,传入我们自己想要的函数,就得到一个新的数组作为结果
function pow(x){
return x * x
}
var arr = [1,2,3,4,5]
console.log(arr.map(pow))
执行结果如下:
reduce方法
定义:接收一个函数作为累加器,数组中的每一个值从左到右开始遍历,最终计算为一个值
注意:对空数组不执行回调
语法格式
new Array().reduce(callback,initialValue(val))
对语法格式的理解
reduce(callback,initialValue)会传入两个变量,第一个参数是回调函数(callback)和第二个初始值(initialValue)。第一个参数回调函数(callback)有四个传入参数,prev和next,index和array。prev和next是必传的参数。