美文网首页
柯里化函数

柯里化函数

作者: 妹姐在线 | 来源:发表于2021-02-10 11:40 被阅读0次

    柯里化的目的在于避免频繁调用具有相同参数函数的同时,又能够轻松的重用

    // 假设我们有一个求长方形面积的函数
    function getArea(width, height) {
        return width * height
    }
    // 如果我们碰到的长方形的宽老是10
    const area1 = getArea(10, 20)
    const area2 = getArea(10, 30)
    const area3 = getArea(10, 40)
    
    // 我们可以使用闭包柯里化这个计算面积的函数
    function getArea(width) {
        return height => {
            return width * height
        }
    }
    
    const getTenWidthArea = getCurryingArea(10)
    // 之后碰到宽度为10的长方形就可以这样计算面积,即上述案例的可以这样写
    const area1 = getTenWidthArea(20)
    const area2 = getTenWidthArea(30)
    const area3 = getTenWidthArea(40)
    
    // 而且如果遇到宽度偶尔变化也可以轻松复用
    const getTwentyWidthArea = getArea(20)
    

    另外一个参数复用的例子

    // 正常正则验证字符串 reg.test(txt)
    
    // 函数封装后
    function check(reg, txt) {
        return reg.test(txt)
    }
    
    check(/\d+/g, 'test')       //false
    check(/[a-z]+/g, 'test')    //true
    
    // Currying后
    function curryingCheck(reg) {
        return function(txt) {
            return reg.test(txt)
        }
    }
    
    var hasNumber = curryingCheck(/\d+/g)
    var hasLetter = curryingCheck(/[a-z]+/g)
    
    hasNumber('test1')      // true
    hasNumber('testtest')   // false
    hasLetter('21212')      // false
    

    像我们js中经常使用的bind,实现的机制就是Currying.

    Function.prototype.bind = function (context) {
        var _this = this
        var args = Array.prototype.slice.call(arguments, 1)
     
        return function() {
            return _this.apply(context, args)
        }
    }
    
    

    curry的一些性能问题你只要知道下面四点就差不多了:

    存取arguments对象通常要比存取命名参数要慢一点
    一些老版本的浏览器在arguments.length的实现上是相当慢的
    使用fn.apply( … ) 和 fn.call( … )通常比直接调用fn( … ) 稍微慢点
    创建大量嵌套作用域和闭包函数会带来花销,无论是在内存还是速度上
    

    其实在大部分应用中,主要的性能瓶颈是在操作DOM节点上,这js的性能损耗基本是可以忽略不计的,所以curry是可以直接放心的使用。

    // 实现一个add方法,使计算结果能够满足如下预期:
    add(1)(2)(3) = 6;
    add(1, 2, 3)(4) = 10;
    add(1)(2)(3)(4)(5) = 15;
    
    function add() {
        // 第一次执行时,定义一个数组专门用来存储所有的参数
        var _args = Array.prototype.slice.call(arguments);
    
        // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
        var _adder = function() {
            _args.push(...arguments);
            return _adder;
        };
    
        // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
        _adder.toString = function () {
            return _args.reduce(function (a, b) {
                return a + b;
            });
        }
        return _adder;
    }
    
    add(1)(2)(3)                // 6
    add(1, 2, 3)(4)             // 10
    add(1)(2)(3)(4)(5)          // 15
    add(2, 6)(1)                // 9
    
    

    作者:flowsands
    链接:https://www.jianshu.com/p/2975c25e4d71
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

          本文标题:柯里化函数

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