JS函数柯里化

函数柯里化是将接受多个参数的函数转化为接受单一参数的函数,返回处理剩余参数的新函数。它能实现参数复用、提前确认和延迟执行。例如,将一个累加函数柯里化后,可以先固定前两个参数,返回一个处理第三个参数的新函数。柯里化增加了代码的可读性和适用性,但也可能影响性能,适用于减少重复参数和作为回调函数等场景。
摘要由CSDN通过智能技术生成

函数柯里化

一、定义

在计算机科学中,柯里化(英语:Currying),指的是把“接受多个参数的函数”变换成“接受单一参数(最初函数的第一个参数) 的函数”,并返回“接受余下的参数而且返回结果的新函数“的技术。

顾名思义,柯里化其实本身是固定一个可以预期的参数,并返回一个特定的函数,处理特定的需求。这增加了函数的适用性,但同时也降低了函数的通用性。

这样的定义不太好理解,我们可以通过下面的例子配合解释:

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

将函数A转化为柯里化函数 _A:

function _A(a){
   
    return function(b){
   
        return a + b
    }
}

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

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

_A能够处理A的所有剩余参数,因此柯里化也被称为部分求值。

实际上就是把A函数的a,b两个参数变成了先用一个函数接收a然后返回一个函数去处理b参数。

现在思路应该就比较清晰了,只传递给函数一部分参数来调用,让它返回一个函数去处理剩下的参数

二、柯里化的通用实现

柯里化,是函数式编程的一个重要概念。它既能减少代码冗余,也能增加可读性。

现在看一个更复杂一点的例子,sum 是个简单的累加函数,接受3个参数,输出累加的结果:

function sum (a, b, c) {
   
    console.log(a + b + c);
}

假设有这样的需求,sum的前2个参数保持不变,最后一个参数可以随意。那么就会想到,在函数内,是否可以把前2个参数的相加过程,给抽离出来,因为参数都是相同的,没必要每次都做运算。调用的写法可以是这样: sum(1, 2)(3)sum(1, 2)(10),先把前2个参数的运算结果拿到后,再与第3个参数相加。这其实就是函数柯里化的简单应用。

sum(1, 2)(3)这样的写法,并不常见。拆开来看sum(1, 2) 返回的应该还是个函数,因为后面还有 (3) 需要执行。那么反过来,从最后一个参数,从右往左看,它的左侧必然是一个函数。以此类推,如果前面有n个(),那就是有n个函数返回了结果,只是返回的结果还是一个函数。是不是有点递归的意思?

function curry (fn, currArgs) {
   
    return function() {
   
        let args = [].slice.call(arguments);

        // 首次调用时,若未提供最后一个参数currArgs,则不用进行args的拼接
        if (currArgs !== undefined) {
   
            args = args.concat(currArgs);
        }

        // 递归调用
        if (args.length < fn.length) {
   
            return curry(fn, args);
        }

        // 递归出口
        return fn.apply(null, args);
    }
}

说明

  • curry有 2 个参数,fn 指的就是源处理函数 ;currArgs 是调用 curry 时传入的参数列表
  • 将 arguments 数组化,arguments 是一个类数组的结构,它并不是一个真的数组,所以没法使用数组的方法。我们用了 call 的方法,就能愉快地对 args 使用数组的原生方法了。
  • args指的是当前柯里化的函数内已获得的所有参数,这个函数最终会传给fn
  • 判断 args 的个数,是否与 fn (也就是 sum )的参数个数相等,相等了就可以把参数都传给 fn,进行输出;否则,继续递归调用,直到两者相等。
    在这里插入图片描述

三、柯里化的作用

  • 参数复用
  • 提前确认
  • 延迟执行
1.参数复用

案例:正则验证字符串

按照普通的思路,验证字符串是否是正确的手机号或者邮箱

//验证手机号
function checkPhone(phoneNumber) {
   
    return /
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值