JS高阶函数与函数柯里化简单实现
本文旨在通俗易懂的讲解下什么是高阶函数,函数柯里化的固定参数与非固定参数两种实现
一、高阶函数是什么?
高阶函数英文叫Higher-order function。
直接上结论:参数为函数 或 返回值为函数 的函数则可以称为高阶函数
常见的高阶函数
Array.map(fn)
Array.reduce(fn)
二、柯里化函数
百度百科:柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。
柯里化函数其实就是高阶函数的一种。它的返回值是一个函数。
柯里化函数–非固定参数个数实现
我们通过一道经典面试题来详细说明
//如下求和函数
function add(a,b,c,d,e){
return a+b+c+d+e
}
//如何使以下结果为true
console.log(add(1)(2) == 3);
console.log(add(1)(2,3)(4) == 10);
console.log(add(1,2)(3)(4)(5) == 15);
实现如下(示例):
//柯里化函数实现
function add(...args){
let arr=args;
var _add = function(...args2){
//收集参数
arr =[...arr,...args2];
//递归调用,永远返回_add函数,使参数可以永远传递下去
return _add;
}
//将输出结果的计算放到toString里
_add.toString = function(){
return arr.reduce((total,num)=>{
return total+num
});
}
return _add;
}
/*
* 注意此处 add(1)(2)..永远返回的是 _add function
* == 相等运算符会做类型转换,本质会去调用function的tostring方法,
* 所以变相调用了 _add.toString
*/
console.log(add(1)(2) == 3); //true
console.log(add(1)(2,3)(4) == 10); //true
console.log(add(1,2)(3)(4)(5) == 15); //true
console.log(add(1)(2).toString()); //3
总结:为传递不定个数的参数,所以返回值就要固定为函数,所以要想真正的计算结果就需要单独有个输出结果的方法,类似上面的toString。或其他自定义方法手动调用。
柯里化函数–固定个数参数实现
柯里化函数固定参数
//请将add方法封装成柯里化函数
function add(a,b,c,d,e){
return a+b+c+d+e
}
//柯里化参数
function curry(fn,arr=[]){
//获得原始函数的形参个数 function.length 返回的是形参个数
let len = fn.length;
//递归方法
return function(...args){
let newArgs = [...arr,...args];
//当参数个数满足原函数个数则执行
if(newArgs.length>=len){
return fn(...newArgs);
}
return curry(fn,newArgs)
}
}
//新的函数
let newAdd = curry(add);
console.log(newAdd(1)(2)(3)); //[Function]
console.log(newAdd(1)(2)(3)(4)(5)); //15
console.log(newAdd(1,2,3)(4)(5)); //15
console.log(newAdd(1,2,3)(4)(5,10)); //15 多余参数被忽略
总结:该实现只接收固定个数参数,多余参数忽略,少数则无法输出期望结果
总结
本文是对柯里化函数的两种简单实现。有问题欢迎留言指正。