#高阶函数
高阶函数叫法:切片编程 AOP
高阶函数满足条件:
1.一个函数的参数是函数。
2.一个函数的返回值是一个函数。
只要满足以上两点的其中一点就属于高阶函数。它可以满足我们在一个函数原有的逻辑上增加一些功能。
/*
需求是想在调用say之前做一些逻辑
*/
let say = (...arge) => {
console.log('笑',...arge)
};
// 在Function原型上添加before方法 参数是个函数 返回也是个函数(高阶函数)
Function.prototype.before = function (cb) {
return (...arge) => { // 使用箭头函数保证this可以拿到before的调用者 这里也就是say
cb()
this(...arge)
}
}
// 调用say上的before 返回一个函数
let newSay = say.before(function(){
console.log('糖')
})
newSay('哈哈哈','嘻嘻嘻');
函数柯里化
函数柯里化是函数式编程的重要思想,也是高阶函数中一个重要的应用,其含义是给函数分步传递参数,每次传递部分参数,并返回一个更具体的函数接收剩下的参数,这中间可嵌套多层这样的接收部分参数的函数,直至返回最后结果。
也就数说把函数范围缩小,变的更具体。
// 检查content是不是type类型
function checkType (content,type) {
return Object.prototype.toString.call(content) === `[object ${type}]`
}
// 一般情况下我们直接这样使用
console.log(checkType('哈哈哈','String'))
// 柯里化一下
function checkType (type) {
return function(content){
return Object.prototype.toString.call(content) === `[object ${type}]`;
}
}
let isString = checkType('String');
console.log(isString('哈哈哈哈哈'));
柯里化通用式
我们接下来封装一个通用的柯里化转换函数,可以将任意函数转换成柯里化。
// 累加函数
const add = (a, b, c, d, e) => {
return a + b + c + d + e
}
// 柯里化通用式
let currying = (fn, ...arr) => {
let len = fn.length;
return (...arge) => {
arr = [...arr, ...arge];
if (arr.length < len) {
return currying(fn, ...arr)
};
return fn(...arr)
}
}
// 通过currying对add进行柯里化
console.log(currying(add, 1, 2)(3)(4, 5))
用checkType方法结合柯里化通用式(currying )使用:
// 柯里化通用式
let currying = (fn, ...arr) => {
let len = fn.length;
return (...arge) => {
arr = [...arr, ...arge];
if (arr.length < len) {
return currying(fn, ...arr)
};
return fn(...arr)
}
}
// 检查content是不是type类型
let checkType = (type,content) => {
return Object.prototype.toString.call(content) === `[object ${type}]`
}
let isString = currying(checkType)('String');
let isBoolean = currying(checkType,'Boolean');
console.log(isString('hahhahahahah'));
console.log(isBoolean(false));
反柯里化
反柯里化的思想与柯里化正好相反,如果说柯里化的过程是将函数拆分成功能更具体化的函数,那反柯里化的作用则在于扩大函数的适用性,使本来作为特定对象所拥有的功能函数可以被任意对象所使用。
反柯里化通用式
// 反柯里化通用式
let uncurring = (fn) => {
return (...args) => {
return fn.call(...args);
}
}
通过一个例子来感受一下反柯里化的应用。
// 反柯里化通用式应用
// 构造函数 F
function F() {}
// 拼接属性值的方法
F.prototype.concatProps = function () {
let args = Array.from(arguments);
return args.reduce((prev, next) => `${this[prev]}&${this[next]}`);
}
// 使用 concatProps 的对象
let obj = {
name: "杰克",
age: 16
};
// 使用反柯里化进行转化
const concatProps = uncurring(F.prototype.concatProps);
concatProps(obj, "name", "age");