js函数柯里化

110 阅读2分钟

什么是函数柯里化 是一种将接受多个函数的参数转化为一系列接受单个参数的函数的技术 有如下几个作用 1参数复用:可以创建接收部分参数的函数。将返回的新函数复用在不同的上下文中。这样可以减少重复的代码。 2延迟执行:当我们传递部分参数给柯里化函数时,它会返回一个新的函数。我们可以在需要的时候再传递余下的参数,从而实现延迟执行 3参数传参更灵活:可以选择一次性传递,也可以分次传参 4高阶函数的应用:实现更加抽象高级的功能.

其实闭包的其中一种应用是函数柯里化 以下可以理解为延迟执行例子

以下是参数复用的例子

    function uri_curry(protocol){
        return function (hostname,pathname){
            return protocol+hostname+pathname
        }
    }
    const uri_base=uri_curry('https://')//这里进行了参数的复用
    const uri1=uri_base('www.baidu.com','/a')
    const uri2=uri_base('www.baidu.com','/b')

柯里化还可以进行浏览器兼容性检查 addEventListener和attachEvent 不同的浏览器对它们的支持是不一样的

const whichEvent=(function(){
        if(window.addEventListener){
           return function(element,type,listener,useCapture){
            console.log('element',element)
            console.log('type',type)
            //element:元素对象
            //type:需要添加什么类型的事件
            //listener:执行的回调函数
             element.addEventListener(type,function(e){
                 listener.call(element,e)//用call规避this的指向问题
                 //e:把原来函数里隐藏的event对象代入到参数里面
             },useCapture)//useCapture是否支持冒泡
           }
        }else if(window.attachEvent){
            return function(element,type,handler){
                //元素,类型,执行函数
                element.attachEvent('on'+type,function(e){
                    handler.call(element,e)
                })
            }

        }
    })()
   具体调用就是
    const id=document.getElementById('test')
    id.addEventListener('click', function() {
          console.log('box1');
    }, false);

参数复用

const nameList=[
    {mid:"one1",pro:"pro"},
    {mid:"one2",pro:"pro"},
    {mid:"one3",pro:"pro"},
    {mid:"one4",pro:"pro"},  
]
const curring=name=>element=>element[name]
const name_mid=curring('mid')
console.log(nameList.map(name_mid)) //利用了map里的遍历

面试相关 前提是已经知道了相加的逻辑

function add(){
    let args1=Array.prototype.slice.call(arguments)
    let inner1=function(){
        args1.push(...arguments)
        console.log('args',args1)
        return inner1
    }
    inner1.toString=function(){
        return args1.reduce((pre,cur)=>{
            return pre+cur
        })
    }
    return inner1
}
const result=add(1)(2)(3)(4).toString()//注意这里进行了隐式转换
//add(1,2,3)(4)  //这里可以调用多次
//add(1,2)(3,4)
console.log('result',  result)
console.log('result', typeof result)

以下是通用的逻辑

function currying(fn){
    var args=Array.prototype.slice.call(arguments,1)
    return function(){
       var _inArgs=Array.prototype.slice.call(arguments)
        return fn.call(null,...args.concat(_inArgs))
    }
}

function square(i){
    return i*i
}
function double(i){
    return i*2
}
function map(handler,list){
    return list.map(handler)
}

var mapS=currying(map,square)
console.log(mapS([1,2,3])) //不好的地方,只能调用两次。不是无限的