高阶函数
1、参数是一个函数 2、函数返回值是一个函数 满足其中一点 就被称为高阶函数
函数的before
意思就是再执行一个函数之前先执行某函数。
//比如我们有个方法是吃饭,吃饭之前呢我们需要做饭。
function eat(){
console.log('吃饭')
}
//做饭
function cooking(){
console.log("做饭")
}
// 我们要实现一个这种功能的方法 打印结果为 做饭 、 吃饭
// let lunch = eat.before(cooking)返回的也是一个函数
// lunch()
// before作为一个函数的方法,我们只能扩展到原型上
Function.prototype.before = function(beforeFn){
return (...arg)=>{ //箭头函数的this是当前作用域的this,箭头函数没有arguments
beforeFn()
this(...arg)
}
}
let lunch = eat.before(cooking)//返回的也是一个函数
lunch()
类型判断封装
// 目前最好的办法是用 Object.prototype.toString.call()
//例如
console.log(Object.prototype.toString.call('123')) //[object String]
// 我们如果想做一个通用方法
// checkType('123') //能得到正确的结果 需要怎么做呢
//通常我们这么做
function isType(obj){
return Object.prototype.toString.call(obj).slice(8,-1)
}
console.log(isType(123)) //Number 没问题
//不过我们是封装 ,我们想直接返回Boolean
// 这样改
// function checkType(obj,type){
// console.log(Object.prototype.toString.call(obj))
// return Object.prototype.toString.call(obj) === `[object ${type}]`
// }
// 测试
console.log(checkType(123,"Number")) //true 没问题 不过我们不满足,我们既然是封装 肯定是使用者怎么简单怎么来。
// 于是我们想是不是可以这样 isNumber()、isString().... 这样还能防止使用者 写错参数 例如类型全写小写了 等等
//还想使用者尽量少的传入参数,毕竟 类型是固定的
let types = ['String','Number','Object','Array','Function','Boolean']
let typeUtil = {}
// 既然我们只需要传入一个参数,那么type是需要内置的
// 需要改造checkType函数
function checkType(type){
return (obj)=>{
return Object.prototype.toString.call(obj) === `[object ${type}]`
}
}
types.forEach((type)=>{
typeUtil[`is${type}`] = checkType(type)
})
console.log(typeUtil.isNumber(123))
柯里化
// 柯里化
const add = (a,b,c,d)=>{
return a+b+c+d
}
const curry = (fn,arr=[])=>{
let len = fn.length
return (...arg)=>{
//累加参数 拿参数数组的长度和参数函数的长度做比较
arr = arr.concat(arg)
//如果参数不够 继续执行curry
if(arr.length<len){
return curry(fn,arr)
}
// 如果参数够了直接执行参数函数
return fn(...arr)
}
}
let curry1 = curry(add)
console.log(curry1(2)(3,4)(5))
更详细柯里化的请移步:segmentfault.com/a/119000001…
函数的after
//after 意思是执行一定次数后执行一个方法,例如下边函数 执行count次后再执行fn函数
function after(count,fn){
return ()=>{
//这里说说 count-- 和 --count 很好解释 减号在前边就会立刻执行减一操作 在后边 下次才会执行
if(--count === 0){
fn()
}
}
}
function callBack(){
console.log("两次一会执行结果")
}
let countAfter = after(2,callBack)
countAfter()
countAfter() //执行两次以后执行结果
// *实现解析 利用闭包的原理 存储count数 每执行一次做一次减减* 完成条件执行函数