Javascript 高阶函数

634 阅读2分钟

高阶函数

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数  每执行一次做一次减减* 完成条件执行函数