js函数柯里化-面试手写版

本文介绍了JavaScript中的函数柯里化概念,通过实例展示了柯里化求和函数的实现,并探讨了通用柯里化函数的编写。讨论了柯里化的预加载参数和动态创建函数的优势,以及在React中的应用。文章强调了柯里化的核心在于利用闭包和作用域,提供了一种优化代码和提高复用性的方法。
摘要由CSDN通过智能技术生成

概念

用我自己的话来总结一下,函数柯里化的意思就是你可以一次传很多参数给curry函数,也可以分多次传递,curry函数每次都会返回一个函数去处理剩下的参数,一直到返回最后的结果。

实例

这里还是举几个例子来说明一下:

柯里化求和函数

    // 普通方式
    var add1 = function(a, b, c){
   
        return a + b + c;
    }
    // 柯里化
    var add2 = function(a) {
   
        return function(b) {
   
            return function(c) {
   
                return a + b + c;
            }
        }
    }

这里每次传入参数都会返回一个新的函数,这样一直执行到最后一次返回a+b+c的值。
但是这种实现还是有问题的,这里只有三个参数,如果哪天产品经理告诉我们需要改成100次?我们就重新写100次?这很明显不符合开闭原则,所以我们需要对函数进行一次修改。

var add = function() {
    var _args = [];
    return function() {
        if(arguments.length === 0) {
            return _args.reduce(function(a, b) {
                return a + b;
            })
        }
        [].push.apply(_args, arguments);
        return arguments.callee;
    }
}
var sum = add();
sum(100, 200)(300);
sum(400);
sum(); // 1000

我们通过判断下一次是否传进来参数来决定函数是否运行,如果继续传进了参数,那我们继续把参数都保存起来,等运行的时候全部一次性运行,这样我们就初步完成了一个柯里化的函数。

通用柯里化函数

这里只是一个求和的函数,如果换成求乘积呢?我们是不是又需要重新写一遍?仔细观察一下我们的add函数,如果我们将if里面的代码换成一个函数执行代码,是不是就可以变成一个通用函数了?

var curry = function(fn) {
    var _args = [];
    return function() {
        if(arguments.length === 0) {
            return fn.apply(fn, _args);
        }
        [].push.apply(_args, arguments);
        return arguments.callee;
    }
}
var multi = function() {
    return [].reduce.call(arguments, function(a, b) {
        return a + b;
    })
}
var add = curry(multi);
add(100, 200, 300)(400);
add(1000);
add(); // 2000


在之前的方法上面,我们进行了扩展,这样我们就已经实现了一个比较通用的柯里化函数了。
也许你想问,我不想每次都使用那个丑陋的括号结尾怎么办?

var curry = function(fn) {
   
    var len = fn.length,
        args = [];
    return function() {
   
        Array.prototype.push.apply(args, arguments)
        var argsLen = args.length;
        if(argsLen < len) {
   
            return arguments.callee;
        }
        return fn.apply(fn, args);
    }
}
var add = function(a, b, c) {
   
    return a + b + c;
}

var adder = curry(add)
adder(1)(2)(3)

这里根据函数fn的参数数量进行判断,直到传入的数量等于fn函数需要的参数数量才会返回fn函数的最终运行结果,和上面那种方法原理其实是一样的,但是这两种方式都太依赖参数数量了。
我在简书还看到别人的另一种递归实现方法,其实实现思路和我的差不多吧。

// 简单实现,参数只能从右到左传递
function createCurry(func, args) {
   

    var arity = func.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值