高阶函数的概念, 以下两个条件满足任何一个都是高阶函数
- 一个函数返回一个函数
- 一个函数可以接受一个函数 高阶函数
function fn(){
cb()
}
高阶函数的使用
假设我们现在有一个需求,我们需要给函数添加一些额外的逻辑,但是并不改变核心的代码
function core(){
console.log('core')
}
Function.prototype.before=function(cb){
return ()=>{
cb()
this()
}
}
let newCore=core.before(()=>{
console.log('before')
})
newCore()
运用高阶函数我们就可以实现这个效果
闭包的概念
什么叫闭包? 函数的定义是有作用域的概念的,一个函数的作用域和执行的作用域不在同一个,那么就会出现闭包
函数柯里化
函数柯里化 多个参数的传入 把它转化成n个函数,这样写的好处就是可以暂存变量。函数柯里化可以解决闭包内存溢出的问题。一般柯里化要求都是一个个的传。这种函数我们叫做偏函数,柯里化是一种定参的规范
function fn(a){
return function a(b){
return function b(){
}
}
}
fn(a,b,c)
let fn1=fn(a)
let fn2=fn1(b)
let xxx=fn2(b)
函数柯里化场景
判断变量类型
typeof 一般用来判断基础类型。 除了这个以外,我们用的比较多的还有instanceof 也可以通过原型的toString方法来放回原型的具体类型
Object.prototype.toString.call()
function isType(val,typing){
return Object.prototype.toString.call(val)==`[object ${typing}]`
}
console.log(isType(null,'String'))
修改上面这个函数,让他的作用域变得更加大一点
function isString(typing){
return function(val){
return Object.prototype.toString.call(val)==`[object ${typing}]`
}
}
let myIsString=isString('String')
myIsString('abc')
myIsString(123)
我们每次执行都可以传入剩余的这些参数。可以通过上面这种写法实现一个通用的柯里化函数.可能还会存在参数个数未知的柯里化。但是一般碰到的函数柯里化参数个数都是已知的。如果碰到未知的柯里化函数问题。我们可以考虑递归处理该函数
function curring(){
const inner=(args=[])=>{
return args.length=>fn.length?fn(...args):(...userArgs)=>inner([...args,...userArgs])
} // 递归返回函数
return inner()
}
function sum(a,b,c,d){
return a+b+c+d
}
let sum1=currying(sum)
let sum2=sum1(1)
let sum3=sum(2,3)
let result=sum3(3,4)
console.log(result)
但是要记住一个问题,那就是sum只有4个参数。你如果定义一个sum4再传入一个5就会报错。处分你对sum进行修改
function sum(...args){
return [...args].reduce((a,b)=>{return a+b},0)
}
再次修改上方的类型判断函数,让他更加符合正常代码编写的柯里化入参规范
function isType(typing,val){
return Object.prototype.call(val)==`[object ${typing}]`
}
let isString=curring(isType)('String')
console.log(isString('abc'))
let isNumber=curring(isType)('isString')
console.log(isNumber('abc'))
封装一个工具类,扩展判断变量类型方法
function isType(typing,val){
return Object.prototype.toString.call(val)==`[object ${typing}]`
}
let util={}
['String','Number','Boolean','Null','Undefined'].forEach((element)=>{
util['is'+element]=curring(isType)(element)
})
console.log(util.isString('abc'))
8行封装了一个变量类型判断方法。用户也不用再去传递对应的变量类型,直接调用函数方法