Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用

详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用

作者头像
watermelo37
发布于 2025-01-22 13:27:36
发布于 2025-01-22 13:27:36
12100
代码可运行
举报
文章被收录于专栏:前端专精前端专精
运行总次数:0
代码可运行

作者:watermelo37 涉及领域:Vue、SpingBoot、Docker、LLM、python等 --------------------------------------------------------------------- 温柔地对待温柔的人,包容的三观就是最大的温柔。 ---------------------------------------------------------------------

详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用

柯里化(Currying)是函数式编程中的一颗璀璨明珠,它不仅提升了代码的灵活性与可重用性,还提供了一种全新的函数设计思路。本篇博客将带你深入了解柯里化,从概念到实际应用,从简单实现到底层机制,全面解析这一强大的编程技术。

一、什么是柯里化?

1、原理解析

柯里化是将一个接受多个参数的函数转换为一系列单参数函数的过程。换句话说,柯里化后的函数会逐步接收参数,每次只接收一个或部分参数,直到收集到足够的参数时才真正执行。

柯里化的概念源于逻辑学家哈斯凯尔·柯里(Haskell Curry),他的研究为函数式编程奠定了理论基础。如今,柯里化已成为现代编程语言中的重要组成部分,尤其在函数式编程语言(如 Haskell、Scala)和 JavaScript 等动态语言中广泛应用。

2、一个直观的例子

假设我们有一个普通的求和函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function sum(a, b, c) {
  return a + b + c;
}

使用柯里化后,我们可以这样调用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const curriedSum = curry(sum);
const result = curriedSum(1)(2)(3); // 6

甚至可以分步调用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const partialSum = curriedSum(1); // 固定第一个参数
const result = partialSum(2)(3); // 6

这种灵活的调用方式得益于柯里化的设计。

curry(柯里化的核心函数)是一种用于将多参数函数转化为逐步接收参数的函数的工具。在 JavaScript 中,curry 函数通常实现为一个高阶函数,它接收一个原始函数作为参数,并返回一个新的函数,可以逐个或分批接收原始函数的参数。

二、如何实现柯里化?

1、底层实现

让我们从零实现一个通用的 curry 函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...args2) {
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}
2、工作原理解析
  1. 初次调用:外层 curry 函数接受一个目标函数 fn。
  2. 参数累积:curried 函数检测当前参数数量是否满足 fn 的参数要求(fn.length)。
  3. 递归调用:如果未满足,则返回一个新函数,继续接收剩余参数。
  4. 执行原函数:当参数数量足够时,调用 fn 并返回结果。
3、测试我们的实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function multiply(a, b, c) {
  return a * b * c;
}

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...args2) {
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}


const curriedMultiply = curry(multiply);
console.log(curriedMultiply(2)(3)(4)); // 24
console.log(curriedMultiply(2, 3)(4)); // 24
console.log(curriedMultiply(2)(3, 4)); // 24

三、柯里化的优点

1. 参数复用

通过固定部分参数,柯里化使函数调用更加灵活。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function greet(greeting, name) {
  return `${greeting}, ${name}!`;
}

const sayHello = curry(greet)("Hello");
console.log(sayHello("Alice")); // Hello, Alice!
console.log(sayHello("Bob"));   // Hello, Bob!
2. 延迟执行

柯里化允许延迟计算,直到所有参数准备就绪。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const add = curry((a, b) => a + b);
const addFive = add(5);
console.log(addFive(10)); // 15
3. 函数组合

柯里化与函数组合结合使用时,能够提升代码的可读性和模块化程度。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const compose = (f, g) => (x) => f(g(x));
const addOne = (x) => x + 1;
const double = (x) => x * 2;

const addOneThenDouble = compose(double, addOne);
console.log(addOneThenDouble(3)); // 8

通过柯里化,我们可以轻松定义和组合类似的函数。

四、为什么柯里化如此强大?

柯里化的核心在于其函数设计理念,它将复杂的操作分解为简单的步骤,每个步骤只关注一个变量。这种设计符合数学中 "单一变量函数" 的思想,使代码更加纯粹、可测试和易于推导。

此外,柯里化为函数式编程的核心特性 "无副作用" 提供了有力支持。柯里化函数通常不会修改全局状态,而是通过参数传递上下文,使代码更加健壮。

五、实际应用场景

1. 高阶函数:Redux Selector 的场景模拟

在 Redux 的 reselect 库中,柯里化用于创建高性能的 memoized 选择器:

假设我们管理一个电商网站,用户的购物车和订单状态保存在 Redux 状态树中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const selectCart = (state) => state.cart;
const selectCartItems = createSelector(
  selectCart,
  (cart) => cart.items
);

const selectCartTotal = createSelector(
  selectCartItems,
  (items) => items.reduce((total, item) => total + item.price * item.quantity, 0)
);

const cartTotal = selectCartTotal(state);
console.log(`Cart Total: $${cartTotal}`);

在这个例子中,柯里化使得创建高性能的派生数据函数变得轻而易举,避免了重复计算。

2. 数据管道:构建复杂的数据流

在实际场景中,柯里化可以用于构建复杂的数据流处理。

例如,一个社交媒体平台需要处理一系列数据操作,包括过滤敏感词、格式化文本、统计字数等:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const filterSensitiveWords = curry((words, text) => 
  words.reduce((acc, word) => acc.replace(new RegExp(word, 'gi'), '***'), text)
);
const formatText = (text) => text.trim().toLowerCase();
const countWords = (text) => text.split(/\s+/).length;

const processTextPipeline = compose(
  countWords,
  formatText,
  filterSensitiveWords(['badword', 'offensive'])
);

const result = processTextPipeline(" This is a BadWord example! Badword is offensive. ");
console.log(result); // 输出处理后的字数

这种数据管道式的构建方式,结合柯里化和函数组合,极大提升了代码的可读性和维护性。

3. 深度嵌套函数的优化

柯里化还能简化深度嵌套的调用,避免回调地狱。例如,假设我们要处理一系列 API 数据请求:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const fetchWithAuth = curry((authToken, endpoint) => 
  fetch(endpoint, { headers: { Authorization: `Bearer ${authToken}` } })
);

const fetchUserData = fetchWithAuth('my-secure-token');

Promise.all([
  fetchUserData('/api/user/1'),
  fetchUserData('/api/user/2')
])
  .then(([user1, user2]) => Promise.all([user1.json(), user2.json()]))
  .then(console.log)
  .catch(console.error);

通过柯里化,我们可以轻松创建基于上下文的高阶函数,避免了大量重复代码。

六、总结

柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。

从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅!

只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
函数柯里化
原文链接:https://note.noxussj.top/?source=cloudtencent 什么是函数柯里化? 函数柯里化(Haskell Brooks Curry),当一个函数有多个参数的
菜园前端
2023/06/06
3040
进大厂之必会的函数柯里化(Currying)
curry是一种处理函数的高级技术。它不仅在JavaScript中使用,也在其他语言中使用。
公众号---人生代码
2021/03/16
5830
JavaScript 柯里化
当 curry(sum)执行后返回一个函数,以 curriedSum(1)(2,3) 为例,实际就是curried(1)
上山打老虎了
2022/06/15
3210
浅谈柯里化
浅谈柯里化 http://zoo.zhengcaiyun.cn/blog/article/currying
政采云前端团队
2023/02/27
3020
浅谈柯里化
一文带你搞懂JavaScript Currying(柯里化)函数
柯里化(Currying)是一种关于函数的高阶技术。它不仅被用于 JavaScript,还被用于其他编程语言。
前端进阶者
2021/10/08
1.7K0
一文带你搞懂JavaScript Currying(柯里化)函数
JavaScript执行机制:变量提升、作用域链、词法作用域、块级作用域、闭包和this
所以,JavaScript是ArkTS的基础,本文就来介绍一下JavaScript执行机制的一些核心概念。
陆业聪
2024/07/23
2210
JavaScript执行机制:变量提升、作用域链、词法作用域、块级作用域、闭包和this
前端进阶|由浅入深的理解函数柯里化
柯里化(Currying)和反柯里化(Uncurrying)在JavaScript中总感觉属于一种不温不火的存在,甚至有些开发者在提起柯里化和反柯里化时,竟然会有点生疏不懂。其实不然,对于它们的概念可能在日常开发中不太提到,但是它们的思想和用法,却在前端开发中经常借鉴和使用,它可以帮助我们写出更加优雅、灵活的代码。本文会首先介绍柯里化的概念、实现原理和应用场景,希望对大家能有所帮助!
anyup
2023/11/27
5750
前端进阶|由浅入深的理解函数柯里化
JavaScript 柯里化
柯里化即 Currying,是一门编译原理层面的技术,用途是实现多参函数,其为实现多参函数提供了一个递归降解的实现思路——把接受多个参数的函数变换成接受第一个参数的函数,并且返回接受剩余参数且返回结果的新函数。
Leophen
2021/08/12
5970
【基于 JS 函数式编程-3】柯里化 | 偏函数 | 组合与管道
定义:接受可变数量参数的函数,称为变参函数。 在es5中我们可以通过arguments来捕获调用变参函数的额外参数。 在es6中,我们可以使用扩展运算符:"..."实现变参函数。如:
前端修罗场
2023/10/07
3810
【基于 JS 函数式编程-3】柯里化 | 偏函数 | 组合与管道
JS中的柯里化
柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
前端下午茶
2018/10/22
5K0
聊一聊如何像大神一般玩转 JavaScript 的高级用法
众所周知,JavaScript是一种非常流行的编程语言,它已经成为了网页开发的必备技能。但是,在我们从事JavaScript编程的时候,我们却没有完全发掘和利用它的全部潜力。在本文中,我们将分享一些高级的JavaScript技巧,希望帮助掘友们更好地理解和掌握JavaScript编程。
前端达人
2023/09/21
2570
聊一聊如何像大神一般玩转 JavaScript 的高级用法
大佬,JavaScript 柯里化,了解一下?
柯里化, 即 Currying 的音译。Currying 是编译原理层面实现多参函数的一个技术。
沃趣科技
2018/05/15
1.5K0
大佬,JavaScript 柯里化,了解一下?
前端工程师的函数式编程
函数式编程 什么是函数式编程 函数式编程是一种编程范式。 面向过程开发 const a = 1 const b = 2 const result = a + b 复制代码 class Calculator { add(a,b) { return a+b } } const c = new Calculator() c.add(1,2) 复制代码 function add(a,b) { return a+b } return a+b 复制代码 面向对象编程 class Calculator
19组清风
2021/11/15
3120
JS手撕(四) call、apply、bind、柯里化、偏函数
所以原理就是给传入的第一个参数添加临时方法,然后去调用这个临时方法,这个时候,这个方法的this就会指向第一个参数啦,最后当然还要临时方法删除掉,不留下痕迹。
赤蓝紫
2023/01/01
5170
翻译连载 |《你不知道的JS》姊妹篇 |《JavaScript 轻量级函数式编程》- 第 3 章:管理函数的输入
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 第 3 章:管理函数的输入(Inputs) 在第 2 章的 “函数输入”
iKcamp
2018/01/04
1.6K0
javascript中柯里化
当函数有多个参数的时候我们对函数进行改造并返回一个函数,只传入部分参数,只到函数执行完毕f(1,2,3) ==> f(1)(2)(3)
开水泡饭
2022/12/26
4120
函数式编程了解一下(上)
所以我们说,函数式编程是一种范式,我们能够以此创建仅依赖输入就可以完成自身逻辑的函数。这保证了当函数多次调用时,依然可以返回相同的结果。因此可以产生可缓存的、可测试的代码库
Nealyang
2019/09/29
5490
函数式编程了解一下(上)
常用JS函数-数组扁平化,缓存函数,柯里化函数,防抖和节流函数
这个数组有很多层,我们现在需要将它变成一层的应该怎么做呢?结合我们前面讲过的reduce和递归我们很容易写出这个方法:
蒋鹏飞
2020/10/15
9360
Js-函数式编程 前言什么是函数式编程为什么Js支持FP纯函数柯里化组合 compose范畴学functorMonadApplicative FunctorFunctor\Monad\Applic
JavaScript是一门多范式语言,即可使用OOP(面向对象),也可以使用FP(函数式),由于笔者最近在学习React相关的技术栈,想进一步深入了解其思想,所以学习了一些FP相关的知识点,本文纯属个人的读书笔记,如果有错误,望轻喷且提点。
菜的黑人牙膏
2019/04/09
1.8K0
Js-函数式编程
		前言什么是函数式编程为什么Js支持FP纯函数柯里化组合 compose范畴学functorMonadApplicative FunctorFunctor\Monad\Applic
深入理解JavaScript函数式编程
什么是函数式编程(Functional Programming, FP):FP 是编程范式之一.(还有面向过程编程、面向对象编程)
用户3045442
2020/07/31
4.5K0
深入理解JavaScript函数式编程
推荐阅读
相关推荐
函数柯里化
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验