最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 中高级前端面试高频题之函数柯里化

    正文概述 掘金(茶无味的一天)   2021-06-22   1034

    这是我参与更文挑战的21天,活动详情查看 更文挑战

    函数柯里化是一种编程方式,它提供了把一个抽象函数作为参数送给另一个函数的方法,以此来做到调用和实现的分离,简单讲就是:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数,所以表现形式上通常有着多次接受参数的特点。

    让我们假定一个carry函数为柯里化方法,用以下例子来展示柯里化函数效果:

    var fn = curry(function(a, b, c) {
        console.log(a + b + c)
    })
    fn(1,2,3) // 6
    fn(1)(2)(3) // 6
    fn(1, 2)(3) // 6
    fn(1)(2, 3) // 6
    

    在经过柯里化之后的函数fn,无论使用以上哪种方式调用,最后返回的结果都一样。我们不难看出柯里化的函数有个应用特点:多次传递参数,参数未处理完则返回函数。

    常见面试题:实现一个函数让 fn(1)(2) === 3

    function curry(fn, arg = []) {
        return function() {
            const _args = arg.slice(0)
            for(let i = 0; i < arguments.length; i++) {
                _args.push(arguments[i]) // 每次把函数参数组合传递给下次调用使用
            }
            if(_args.length < fn.length) { // Currying传入的参数少于接收参数的数量,继续接受参数的函数
                return curry.call(this, fn, _args)
            } else {
                return fn.apply(this, _args) // 最后返回计算结果
            }
        }
    }
    
    const fn = curry(function(a, b) {
        return a + b
    })
    
    console.log(fn(1)(2) === 3) // true
    

    以上解题步骤使用到了call、apply、递归、数组拷贝,可视为对这些基础知识的运用考察。

    浅显地来看,柯里化的一个关键点在于传递参数没有达到定义函数的数量则不会停下来返回结果,所以通常可以想到的应用场景如下:

    // 假设如下一段代码
    fn(a, b, c) {
      // ... TODO
    }
    const a = fn('head', 'foot', 'content111')
    const b = fn('head', 'foot', 'content222')
    
    // 利用柯里化就可以“缓存”相同的变量赋值:
    const fn = curry((a, b, c) => {
      // ... TODO
    })
    const x = fn('head', 'foot')
    const a = x('content111')
    const b = x('content222')
    

    emm...但是实际开发中这种场景应该有其它更好的写法,这样做只是充分利用到了函数式编程方式,个人认为实际应用的场景真的并不多见吧。

    我们看到柯里化也是函数中返回一个函数,很像闭包,那么利用闭包缓存参数,就可以做些有趣的事情,比如下面这个“延迟”执行函数。

    假设有如下函数:

    // reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
    const add = (...args) => args.reduce((a, b) => {
        return a + b 
    });
    console.log( add(6,6,6) ); // 立即输出结果 18
    

    改造此函数:

    function delayCurry(func) {
        let args = [];
        return function result(...a) {
            if (arguments.length === 0){ return func(...args) } // 直到没有参数时才返回结果
            args = args.concat([].slice.apply(arguments))
            return result;
        }
    }
    
    const sum = delayCurry(add);
    
    sum(6)(3)(3);
    sum(6);
    console.log( sum() ); // 此时输出结果 18
    

    我对柯里化的探究也只能止步于此,最常见还是在面试当中,而在实际应用下可能还是取决于函数式编程的功底罢。


    起源地下载网 » 中高级前端面试高频题之函数柯里化

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元