高级函数概念理解
- 一个函数的参数为函数
- 一个函数返回值为函数
由此衍生一个问题,日常开发中如何对一个函数方法进行拓展?
此时我们就可以采用高阶函数去实现
高阶函数
首先我们定义一个函数方法
function study(...args) {
console.log('当前我正在' + args)
}
复制代码
我想在此函数上面拓展玩游戏的方法怎么办呢?
首先我们在原型链上定义一个拓展方法before,定义一个玩游戏的方法play函数
Function.prototype.before = function (beforeFn) {
return (...args) => {
beforeFn();
this(...args)
}
}
const play = (...args) => {
console.log('当前我正在' + args)
}
复制代码
之后我们如何去玩呢?
let newFn = study.before(() => {
play('玩游戏')
})
newFn('学习')
复制代码
请看结果,这样我们就实现了拓展,你学废了没有?
柯理化函数
其实柯理化函数就是一个高阶函数,其含义就是给函数分步传递参数,每次传递部分参数,并返回一个更具体的函数接收剩下的参数,这中间可以嵌套多层这样的接收部分参数的函数,直至返回最后的结果。
柯理化函数简单理解就是让一个函数变得更具体些.
举个简单的栗子:
//原函数
function add(a,b,c){
return a+b+c
}
add(1,2,3)
//柯理化函数
function addCurrying(a){
return function(b){
return function(c){
return a+b+c
}
}
}
//调用柯理化函数(充分利用了闭包的特性实现)
addCurrying(1)(2)(3)
复制代码
实现通用性函数
function currying(fn, args) {
//获取形参个数,即fn正常运行时所需参数的长度
let fnLen = fn.length;
//收集函数所传其他参数
args = args || []
return function () {
//将参数转化为数组
let _args = [].slice.call(arguments)
//将上次的参数与当前参数进行合并
Array.prototype.unshift.apply(_args, args);
//可替换成 _args = [...args, ..._args];
//把args数组加入到_args数组的前面,注意执行顺序
//参数不够则继续收集参数
if (_args.length < fnLen) {
return currying.call(null, fn, _args)
}
//如果参数满足,则直接执行
return fn.apply(null, _args)
}
}
复制代码
下面我们要去测试一下,就简单写个测试函数
//判断类型
function isType(type, value) {
return Object.prototype.toString.call(value) === `[object ${type}]`
}
let isString = curry(isType)('String');
let isNumber = curry(isType)('Number');
console.log(isString('abc'));
console.log(isNumber('abc'));
复制代码
由此我们可以得出柯理化另一个优点,通过参数的拆分实现了不同功能的函数
测试结果