最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 一文搞懂函数柯理化

    正文概述 掘金(前端小书)   2021-01-01   527

    什么是函数的柯理化

    柯里化(英语:Currying),又叫函数的部分求值,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

    通俗一点来说

    • 柯里化就是一个函数原本有多个参数,只传入一个参数,生成一个新函数,由新函数接收剩下的参数来运行得到结果.
    • 与柯里化类似的一个概念:高阶函数(可以参考我上一篇文章什么是高阶函数)

    JavaScript高级程序设计里写到

    • 柯里化函数通常由以下步骤动态创建:调用另一个函数并为它传入要柯里化的函数和必要的参数.

    • 高级程序设计上的通用例子:

    function curry(fn) {
        // 获取剩余参数 将类数组转化成数组
        var args = Array.prototype.slice.call(arguments, 1);
        return function() {
            var innerArgs = Array.prototype.slice.call(arguments);
            var finalArgs = args.contact(innerArgs);
            return fn.apply(null, finalArgs);
        }
    }
    function add (num1, num2) {
        return num1 + num2;
    }
    var curriedAdd = curry(add, 5);
    alert(curriedAdd(3); // 8
    

    这个一上来就给出结果可能不好理解,下面我们一步一步来,讲解柯理化的实现步骤及它解决了什么问题

    我们目前有一个函数A

    function A(a, b, c) {
       return a + b + c;
    }
    

    假如我们已经有一个封装好的柯理化函数 curry 他接收 A 作为参数,能够将 A 转化成柯理化函数,返回的结果就是这个被转化后的函数

    var _A = currying(A);
    

    那么 _A 作为柯理化函数,他能够处理 A 剩下的剩余参数,因此要求下面的运行结果都是等价的:

    _A(1, 2, 3);
    _A(1, 2)(3);
    _A(1)(2, 3);
    _A(1)(2)(3);
    A(1, 2, 3);
    

    在简单的场景下,我们凭眼里来封装得到柯理化函数可能是下面这样的

    function myA(a) {
        return function(b) {
          return function(c) {
            return a + b + c;
          }
        }
    }
    

    那么下面的运算方式确实是等价的

    A(1, 2, 3);
    myA(1)(2)(3);
    

    但是按照要求,要求 myA(1, 2)(3) 也要与其他的等价,但并不是,所以,这样封装的柯理化函数自由度偏低,而且有些要求达不到

    因此我们需要知道如何去封装一个柯理化的通用式

    封装如下:

    function curry(fn, args) {
        args = args || []
        var arity = fn.length
        
        return function() {
            var _args = Array.prototype.slice.call(arguments)
            Array.prototype.unshift.call(_args, ...args)
            _args = _args.concat(args)
            
            if (_args.length < arity) {
                return currying.call(null, fn, _args)
            }
            
            return fn.apply(null, _args)
        }
    }
    

    遇到的坑(重要)

    在编写函数柯理化的时候遇到了一些坑,虽然不大,但是没注意的话还是会掉下去的,既然我掉下去了,那么就记录下来防止大家掉下去吧

    函数的长度:Function.length

    问问大家,知道函数的长度吗?

    什么?函数还有长度?不就字符串,数组有长度吗?

    是的,函数有长度,函数的长度就表示 该函数有多少个必须要传入的参数,即形参的个数

    那我们先来看一个例子

    var fn = function(a, b) {}
    console.log(fn.length);
    

    不知道函数的长度的概念的人可能不知道这题的答案,但是根据上面的说法,不是有两个形参吗,那么好,答案不就是 2 吗,好那看下一题

    var fn = function(a, b = []) {}
    console.log(fn.length);
    

    这个打印多少呢?有的人应该就有点蒙了,应该还是 2 吧,我之前也这样以为,但正确答案却是 1 ,那么这是为什么呢

    刚才说了,函数的长度表示该函数有多少个必须要传入的参数,即形参的个数,但是:形参数量不包括剩余参数个数,仅包括第一个具有默认值之前的参数个数,与之对应的是:arguments.length 是函数被调用是实际传参的个数

    好的,知道结论后大家可以将下面的代码拷贝到浏览器控制台粘贴看看答案,加深一下印象

    function fn1(a = () => {}, b = [], c) {}
    function fn2(a, b = [], c) {}
    function fn3(...args) {}
    function fn4() { alert(arguments.length) }
    
    console.log(fn1.length); // 0
    console.log(fn2.length); // 1
    console.log(fn3.length); // 0
    console.log(fn4.length); // 0
    

    起源地下载网 » 一文搞懂函数柯理化

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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