当前位置: 首页 > news >正文

js函数柯里化

柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新技术。

用数学表达式来理解可能更直观:

假设有一个函数f,它接受三个参数:

f(x, y, z) =result

柯里化之后,它变成了这样一系列的嵌套函数:

f(x)+f(y)+f(z)=result

也就是:

fn(x, y, z)变成fn(x)(y)(z)

核心思想:通过闭包缓存参数,直到集齐所有参数才执行最终逻辑。

简单代码示例:

function add(x, y,z) { return x + y + z; } console.log(add(1, 2, 3)); // 输出: 6

柯里化写法

function curriedAdd(x) { return function(y) { return function(z) { return x + y + z }; } } // 或者使用 ES6 箭头函数简化: const curriedAddArrow = x => y => z=>x + y + z; console.log(curriedAdd(1)(2)(3)); // 输出: 6

发生了什么?

  1. curriedAdd(1)执行后,返回了一个记住了x=1的新函数。

  2. 紧接着调用这个新函数并传入2,返回了一个记住了 y=2的新函数。

  3. 紧接着调用这个新函数并传入 3,返回了一个记住了 z=3的新函数。

  4. 内部函数访问闭包中的x和传入的y还有z,计算1 + 2 + 3

通用柯里化函数的实现 (核心技能)

function curry(fn) { // limit 是 fn 声明时定义的参数个数 (arity) const limit = fn.length; return function curried(...args) { // 1. 如果当前收集的参数 args 数量 >= limit,说明参数够了,执行原函数 if (args.length >= limit) { return fn.apply(this, args); //this是window,最后的结果是window.fn } else { // 2. 如果参数不够,返回一个新函数来继续接收剩余参数 (...moreArgs) return function(...moreArgs) { // 将之前的 args 和新的 moreArgs 合并,递归调用 curried return curried.apply(this, args.concat(moreArgs)); } } }; }

测试这个工具

// 一个接受4个参数的普通函数 function sum(a, b, c, d) { return a + b + c + d; } // 将其柯里化 const curriedSum = curry(sum); // 方式 1: 一次性传完 (依然支持) console.log(curriedSum(1, 2, 3, 4)); // 10 // 方式 2: 分步传参 (标准柯里化) console.log(curriedSum(1)(2)(3)(4)); // 10 // 方式 3: 混合传参 (非常灵活) console.log(curriedSum(1, 2)(3)(4)); // 10

使用方向与实战场景 (Use Cases)

你可能会问:“直接传参不好吗?为什么要搞这么麻烦?” 柯里化的主要优势在于:参数复用延迟执行代码组合

场景一:参数复用(创建偏函数)

假设我们需要验证很多个字符串是否符合某种正则表达式(例如验证是否是邮箱,或是否是数字)。

不使用柯里化:

function check(reg, txt) { return reg.test(txt); } // 每次都要传正则 check(/\d+/g, 'test'); // false check(/[a-z]+/g, 'test'); // true check(/\d+/g, '123'); // true

使用柯里化:我们可以固定住“正则”这个参数,生成具体的检测函数。

const curriedCheck = curry(check); // 使用上面定义的 curry 工具 // 创建专门验证数字的函数 (复用了 /\d+/g 参数) const hasNumber = curriedCheck(/\d+/g); // 创建专门验证字母的函数 const hasLetter = curriedCheck(/[a-z]+/g); // 现在使用起来非常语义化,且不用重复写正则 console.log(hasNumber('test')); // false console.log(hasNumber('123')); // true console.log(hasLetter('test')); // true

map等高阶函数配合

在处理数组时,柯里化能让代码极其简洁。

假设我们要获取数组中所有对象的id属性。

const persons = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }]; // 普通写法 const ids1 = persons.map(p => p.id); // 柯里化写法 const getProp = curry((key, obj) => obj[key]); const getId = getProp('id'); // 预设我们要取 'id' // 代码极具可读性:map (获取id) const ids2 = persons.map(getId); console.log(ids2); // [1, 2]

. 总结 (Summary)

优点

  • 复用性:通过固定部分参数,生成功能更具体的小函数(如hasNumber,getId)。

  • 可读性:代码语义更加清晰,接近自然语言。

  • 延迟执行:直到所有参数凑齐前,函数都不会真正运行,可以分阶段积累数据。

  • 函数式编程基石:柯里化让函数变成了“单参数”函数,这使得函数组合(Composition)变得容易得多(类似流水线f(g(x)))。

http://www.jsqmd.com/news/342027/

相关文章:

  • 【计算机毕业设计案例】基于nodejs的宠物医院病宠信息管理系统的设计与实现(程序+文档+讲解+定制)
  • 三角函数完备
  • Note -「Spiking Neural Network」SNN 光速入门
  • 真心不骗你!AI论文网站,千笔·专业论文写作工具 VS 笔捷Ai,本科生专属神器!
  • 【毕业设计】基于php+vue的家教预约服务网页设计与开发(源码+文档+远程调试,全bao定制等)
  • 基于plc的扫描拾取机械手(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 2026年构建企业智慧大脑:五大核心知识库部署厂商推荐榜 - 品牌2025
  • 创客匠人视角:知识产品如何借力AI智能体,从“一次性交付”走向“持续生长”?
  • 2026年单层玻璃隔断供应商推荐:双玻全景玻璃隔断/百叶玻璃隔断/双玻璃隔断供应商精选 - 品牌推荐官
  • 基于PLC的升降横移式立体车库(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 碳排算不清?问题可能不在平台,而在“电表”
  • 上班族早晚餐代餐怎么选?2026低卡饱腹减脂产品深度实测,科学减重营养不打折 - 品牌企业推荐师(官方)
  • 2026转行要趁早!网络安全行业人才缺口大,企业招聘需求正旺!
  • 通用测试上位机的典型应用场景与核心价值
  • 经验分享 从空乘转行网络安全,我入行就拿到月薪13k!
  • 2026年转行互联网哪些方向更合适?
  • 为什么越来越多的人转行网络安全?
  • 2026年必看!生产线源头厂家推荐榜单TOP 5,你知道几个 - 品牌企业推荐师(官方)
  • 为什么0基础转行网络安全,web安全是首选?
  • 为什么运维要转行
  • 2026上班族早晚餐代餐选购指南:低卡饱腹实测,科学减重不缺营养 - 品牌企业推荐师(官方)
  • 运维想转行?运维工程师的出路在哪里,尤其是 35 岁以后?
  • 银座购物卡可以回收吗,1000银座卡回收真实价格 - 淘淘收小程序
  • for /f “skip=1 tokens=3“ %%s in (‘query user %USERNAME%‘) do (%windir%\System32\tscon.exe %%s /dest:
  • 中大型企业选型指南:微信小程序开发公司全流程服务能力对比(硬件小程序、接诉即办小程序开发公司、物联网小程序开发公司推荐) - 品牌2025
  • 2026年焊管机/焊管机组/高频焊管设备厂家实力推荐榜:专业制造与高效稳定性能深度解析 - 品牌企业推荐师(官方)
  • 硕士论文AI检测标准是什么?各高校AIGC疑似度要求汇总
  • 揭秘!激光颗粒计数器最受欢迎的品牌是谁? - 品牌推荐大师
  • 模拟量位置传感器测量的“3R”法则:重复性、分辨率与响应
  • 2026年LNG气化撬/气化调压撬/减压撬装设备厂家推荐:南宫市腾博能源科技有限公司,适配城镇调峰、工业供气与煤改气多场景 - 品牌推荐官