1、什么是高阶函数,常见的高阶函数有哪些?
高阶函数一般具有以下两个规范中的一个
- 函数接收的参数是一个函数,那么函数就称为高阶函数
- 调用的返回值依然是一个函数,那么称之为高阶函数
function add(x,y,z){
return f(x)+f(y)
}
let num =add(2,2,Math.abs)
常见的高阶函数
- Promise
- setTimeout
- arr.map()
- filter
- reduce
高阶函数的一个高级应用就是函数柯里化
2、什么是柯里化
函数柯里化,又称部分求值,他将接受部分参数,返回一个函数接受剩余参数,接收足够参数之后,接收函数。
作用和特点:参数复用,提前返回和延迟执行
3、实现函数柯里化
实现函数的柯里化有两种思路
- 通过函数的length属性,获取函数的形参个数,形参个数就是所需的参数个数
- 在调用柯里化工具函数时,手动指定需要的参数个数
结合这两点实现一个curry函数
// 写法1 推荐
function curry(fn) {
const fnArgsLength = fn.length // 传入函数的参数长度
let args = [] // 收集传入的参数
function calc(...newArgs) {
// 积累参数保存到闭包中
args = [
...args,
...newArgs
]
// 积累的参数长度跟传入函数的参数长度对比
if (args.length < fnArgsLength) {
// 参数不够,返回函数
return calc
} else {
// 参数够了,返回执行结果
return fn.apply(this, args.slice(0, fnArgsLength)) // 传入超过fnArgsLength长度的参数没有意义
}
}
// 返回一个函数
return calc
}
//写法2
{
function currying(fn, length) {
length = length || fn.length;
return function() {
// 实参长度大于fn.length
return arguments.length >= length?
// 满足时,执行fn函数
fn.apply(null, arguments):
//不满足时,递归currying函数,新的fn为bind返回的新函数(绑定了...arguments,但不执行,)
// 新的length为原fn剩余的参数长度
currying(fn.bind(null, ...arguments), length - arguments.length);
}
}
const fn = currying(function(a, b, c){
console.log([a, b, c]);
});
fn('a', 'b', 'c');
fn('a', 'b')('c');
fn('a')('b')('c');
fn('a')('b','c');
}
参考: