”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > JavaScript 柯里化

JavaScript 柯里化

发布于2024-08-07
浏览:709

JavaScript Currying

柯里化是函数式编程中的一个强大概念,它将具有多个参数的函数转换为一系列函数,每个函数接受一个参数。这种技术允许更加模块化和可重用的代码。在 JavaScript 中,柯里化可以通过多种方式实现。本博客将探讨柯里化,提供示例,并讨论实现 n 参数柯里化的不同方法。

什么是柯里化?

柯里化是将采用多个参数的函数转换为一系列每个采用单个参数的函数的过程。例如,函数 f(a, b, c) 可以转换为 f(a)(b)(c).

为什么使用柯里化?

  • 部分应用:柯里化允许你修复函数的一些参数并创建一个新函数。
  • 高阶函数:它方便了高阶函数的使用,这些函数将其他函数作为参数或返回它们。
  • 代码可重用性:柯里化函数更具可重用性和可组合性。
  • 函数式组合:柯里化可以实现更好的函数式组合,通过组合更简单的函数来构建复杂的函数,从而生成更清晰、更易于维护的代码。

简单柯里化示例

让我们从一个基本示例开始来了解柯里化的工作原理。

未柯里化函数

这是一个将三个数字相加的简单函数:

function add(a, b, c) {
  return a   b   c;
}

console.log(add(1, 2, 3)); // Output: 6

说明: 该函数 add 接受三个参数 a、b 和 c,并返回它们的和。当我们调用 add(1, 2, 3) 时,它返回 6.


柯里化函数

现在,让我们将此函数转换为柯里化版本:

function curryAdd(a) {
  return function(b) {
    return function(c) {
      return a   b   c;
    };
  };
}

console.log(curryAdd(1)(2)(3)); // Output: 6

说明:curryAdd 函数接受一个参数 a 并返回一个接受参数 b 的函数,该函数又返回一个接受参数 c 的函数。最终函数返回 a、b 和 c 的总和。当我们调用 curryAdd(1)(2)(3) 时,它通过嵌套函数顺序传递参数 1、2 和 3,结果是 6.

使用箭头函数进行柯里化

JavaScript 的箭头函数提供了一种创建柯里化函数的简洁方法。

const curryAddArrow = a => b => c => a   b   c;

console.log(curryAddArrow(1)(2)(3)); // Output: 6

解释:curryAddArrow 函数是一个箭头函数,它接受参数 a 并返回另一个接受 b 的箭头函数,该函数返回另一个接受 c 的箭头函数。最终箭头函数返回 a、b 和 c 的总和。当我们调用 curryAddArrow(1)(2)(3) 时,它通过嵌套箭头函数顺序传递参数 1、2 和 3,结果是 6.


使用案例

1.配置功能

柯里化的一个常见用例是配置函数。例如,假设您正在创建一个日志记录实用程序,您想要分别配置日志记录级别和消息格式。

function logger(level) {
  return function (message) {
    console.log(`[${level}] ${message}`);
  };
}

const infoLogger = logger('INFO');
const errorLogger = logger('ERROR');

infoLogger('This is an info message');
errorLogger('This is an error message');

2. 字符串格式化程序

让我们考虑一个实际的例子,其中柯里化可用于创建字符串格式化程序。此格式化程序将允许您分别配置前缀和后缀。

function formatter(prefix) {
  return function (suffix) {
    return function (str) {
      return `${prefix}${str}${suffix}`;
    };
  };
}

const htmlFormatter = formatter('')('');
console.log(htmlFormatter('Hello')); // Hello

const parensFormatter = formatter('(')(')');
console.log(parensFormatter('123')); // (123)

现代 JavaScript 库中的柯里化

柯里化通常用于 Lodash 和 Ramda 等现代 JavaScript 库中。例如,在Lodash中,您可以使用_.curry方法轻松创建柯里化函数。

const _ = require('lodash');

function multiply(a, b, c) {
  return a * b * c;
}

const curriedMultiply = _.curry(multiply);

console.log(curriedMultiply(2)(3)(4)); // 24
console.log(curriedMultiply(2, 3)(4)); // 24

使用 N 个参数进行柯里化

让我们看一下下面使用添加 n 个参数的递归函数进行柯里化的示例。我们将使用柯里化创建一个函数,该函数可以接受任意数量的参数(一次一个),并将它们添加在一起。

function curryAddition(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn(...args);
    } else {
      return function(...nextArgs) {
        return curried(...args, ...nextArgs);
      };
    }
  };
}

// This function sums an array of numbers
function add(...nums) {
  return nums.reduce((acc, num) => acc   num, 0);
}

// Creating a curried version of the addition function
const curriedAdd = curryAddition(add);

// Function to handle n arguments
function curriedAddN(...initialArgs) {
  function adder(...args) {
    if (args.length === 0) {
      return curriedAdd(...initialArgs);
    }
    initialArgs.push(...args);
    return adder;
  }
  return adder;
}

// Examples
const addFiveNumbers = curriedAddN();
console.log(addFiveNumbers(1)(2)(3)(4)(5)()); // 15

const addThreeNumbers = curriedAddN(1)(2)(3);
console.log(addThreeNumbers()); // 6

const addNumbersInSteps = curriedAddN(1, 2)(3)(4, 5);
console.log(addNumbersInSteps()); // 15

结论

柯里化是函数式编程中的一种强大技术,可以增强代码的模块化和可重用性。通过将函数转换为单参数函数链,柯里化允许部分应用和灵活的函数组合。无论是配置、字符串格式化还是复杂的计算,柯里化都可以使您的代码更具表现力和适应性。

版本声明 本文转载于:https://dev.to/rahulvijayvergiya/javascript-currying-op2?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    在Python 射线tracing方法Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a路径对象表示多边形。它检查给定点是否位于定义路径内。 T...
    编程 发布于2025-02-07
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 // error:“ coss redeclare foo()” 但是,php工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地...
    编程 发布于2025-02-07
  • 如何从Google API中检索最新的jQuery库?
    如何从Google API中检索最新的jQuery库?
    从Google APIS 问题中提供的jQuery URL是版本1.2.6。对于检索最新版本,以前有一种使用特定版本号的替代方法,它是使用以下语法: https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js(google hosted...
    编程 发布于2025-02-07
  • 如何使用PHP将斑点(图像)正确插入MySQL?
    如何使用PHP将斑点(图像)正确插入MySQL?
    在尝试将image存储在mysql数据库中时,您可能会遇到一个可能会遇到问题。本指南将提供成功存储您的图像数据的解决方案。 easudy values('$ this-> image_id','file_get_contents($ tmp_image)...
    编程 发布于2025-02-07
  • 如何在整个HTML文档中设计特定元素类型的第一个实例?
    如何在整个HTML文档中设计特定元素类型的第一个实例?
    [2单独使用CSS,整个HTML文档可能是一个挑战。 the:第一型伪级仅限于与其父元素中类型的第一个元素匹配。 以下CSS将使用添加的类样式的第一个段落: }
    编程 发布于2025-02-07
  • 如何使用FormData()处理多个文件上传?
    如何使用FormData()处理多个文件上传?
    )处理多个文件输入时,通常需要处理多个文件上传时,通常是必要的。可以将fd.append("fileToUpload[]", files[x]);方法用于此目的,允许您在单个请求中发送多个文件。 初始尝试 在JavaScript中,一种常见方法是:); 但是,此代码仅处理第一...
    编程 发布于2025-02-07
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    [2 _post ['ss'];?> 的目的是从单击提交按钮时,文本框并显示。但是,输出保持空白。当方法=“ get”无缝工作时,方法=“ post”构成问题。 检查action属性:如果您正在刷新页面,请将操作属性设置为空字符串,例如] action ='&#...
    编程 发布于2025-02-07
  • 如何可靠地检查MySQL表中的列存在?
    如何可靠地检查MySQL表中的列存在?
    在mySQL中确定列中的列存在,验证表中的列存在与与之相比有点困惑其他数据库系统。常用的方法:如果存在(从信息_schema.columns select * * where table_name ='prefix_topic'和column_name =&...
    编程 发布于2025-02-07
  • 如何使用char_length()在mySQL中按字符串长度对数据进行排序?
    如何使用char_length()在mySQL中按字符串长度对数据进行排序?
    [2使用内置的char_length()function。 char_length()和length() 此查询将从指定的表中检索所有行,并基于上升顺序对它们进行排序指定列的字符长度。带有更长字符串的行将出现在结果的底部。
    编程 发布于2025-02-07
  • 我可以在CSS中使用SVG作为伪元素吗?
    我可以在CSS中使用SVG作为伪元素吗?
    使用svgs用作pseudo-element content css content properts允许在使用元素之前或之后使用元素插入各种类型的内容伪元素,例如::之前和::之后。但是,对可以包括哪些内容有限制。可以将svgs用作pseudo-element Content?,现在可以使用s...
    编程 发布于2025-02-07
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月份)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将...
    编程 发布于2025-02-07
  • 为什么我的JTEXTAREA使用SwingPropertyChangeSupport修改数组后不会更新?
    为什么我的JTEXTAREA使用SwingPropertyChangeSupport修改数组后不会更新?
    SwingPropertyChangeSupport to Dynamically Update JTextAreaSwingPropertyChangeSupport is a class that can be used to monitor changes in the properties ...
    编程 发布于2025-02-07
  • 如何使用替换指令在GO MOD中解析模块路径差异?
    如何使用替换指令在GO MOD中解析模块路径差异?
    克服go mod中的模块路径差异 coreos/bbolt:github.com/coreos/ [email受保护]:解析go.mod:模块将其路径声明为:go.etcd.io/bbolt `要解决此问题,您可以在go.mod文件中使用替换指令。只需在go.mod的末尾添加以下行:[&& &...
    编程 发布于2025-02-07
  • 为什么导入Numpy将多处理限制为单个核心?
    为什么导入Numpy将多处理限制为单个核心?
    numpy import对多处理core sizgment workaround: 附加注意事项: 没有显着影响关于Numpy的性能,但效果可能会因特定的机器和任务而异。 在编译过程中,将OpenBlas MakeFile.rule修改为Include no_affinity = 1。,通...
    编程 发布于2025-02-07
  • 如何使用Java的JSCH库连接到SSH服务器?
    如何使用Java的JSCH库连接到SSH服务器?
    使用Java 最享有盛誉的Java SSH库之一是Java Secure Channel(JSCH)库。它的受欢迎程度源于其在基于Java的各种工具和应用中的使用,包括Maven,Ant和Eclipse。这是一个在BSD样式许可下分布的开源库。 example: args)抛出异常{ ...
    编程 发布于2025-02-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3