柯里化函数

作者: 姜治宇 | 来源:发表于2020-02-10 16:20 被阅读0次

在解释什么是柯里化函数之前呢,先搞明白另一个概念——高阶函数。
高阶函数,就是一个函数可以接收另一个函数作为参数,看一个例子:

function higerFunc(fn){
    return fn()
}
higerFunc(function(){
    console.log('hello')
})

柯里化函数其实就是高阶函数,它可以将函数拆成两步来执行(延期执行),怎么理解呢?
我们还是看一个例子:

//普通函数
    function check(reg, txt) {
        return reg.test(txt)
    }

    check(/\d+/g, 'test') 
    check(/\d+/g, 'abc123')  
    check(/\d+/g, '789') 
    // Curry化函数,将第一个参数拆分出来复用,第二个参数作为变量。
    function curryingCheck(reg) {
        return function(txt) {
            return reg.test(txt)
        }
    }

    var hasNumber = curryingCheck(/\d+/g)
    hasNumber('test')     
    hasNumber('abc123')   
    hasNumber('789')  

大家能看出区别吗?
柯里化之前的函数,虽然可以一步到位,但正则得写多遍吧,多麻烦啊!而使用了柯里化,虽然拆成两步执行,但可以复用正则表达式,省事不少呢~~
好,下面看一个柯里化的实际使用场景,大家就能深刻理解柯里化的好处了。
大家看这样一个需求:
当点击一个按钮时,如何将额外的数据,传入到这个事件的回调函数中?
我们试着写一下:

var dom = document.getElementById('btn')
    function fn(obj){
        console.log(obj)
    }
    var data = {id:1,title:'this is a test'}//这个data如何传入fn?

    dom.addEventListener('click',fn,false)//无法传入fn(data)

可以这么改造一下即可:

dom.addEventListener('click',function(e){
        fn.call(dom,data)
    },false)

这不就行了?且慢!
如果dom上的click事件挂载了多个,我只想移除特定的某一个,怎么办?

var dom = document.getElementById('btn')
    function fn(obj){
        console.log(obj)
    }
    var data = {id:1,title:'this is a test'}//这个data,如何传入fn?
    
    dom.addEventListener('click',function(e){
        console.log('第1个click事件') //我只想移除这个click
        fn.call(dom,data)
    },false)
    dom.addEventListener('click',function(e){
        console.log('第2个click事件')//我要保存这个click
        fn.call(dom,e)

    },false)

如果用了匿名函数,我们只能将全部click事件移除:

dom.removeEventListener('click')//dom上挂载的click事件全部被移除了

怎么办呢?
这就慢慢绕到柯里化上来了,我们可以将fn柯里化一下:

var dom = document.getElementById('btn')
    function curryFn(obj){

        return function(){
            console.log('data:',obj)//内存持有上下文
            console.log('event:',arguments)//内函数的参数
        }
    }
    var data = {id:1,title:'this is a test'}//这个data,如何传入fn?

    var clickAction = curryFn(data)
    dom.addEventListener('click',clickAction,false)
    //2s后移除事件
    setTimeout(function(){
        dom.removeEventListener('click',clickAction)

    },2000)

我们再将curryFn稍加改造,提升一点逼格:

function curryFn(){
        var outParams = [].slice.call(arguments) //外层函数的参数,也就是data
        return function(){
            console.log('data:',outParams)
            console.log('event:',arguments)//内层函数的参数,也就是event
        }
    }

相关文章

网友评论

    本文标题:柯里化函数

    本文链接:https://www.haomeiwen.com/subject/nwunxhtx.html