一文快速了解JS中的柯里化(Currying)

本篇文章带大家快速了解一下javascript中的柯里化(currying),有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

一文快速了解JS中的柯里化(Currying)

柯里化将多参数函数转换为一元(单参数)函数。【相关推荐:javascript学习教程】

柯里化函数一次接受多个参数。所以如果你有

greet = (greeting, first, last) => `${greeting}, ${first} ${last}`;greet('Hello', 'Bruce', 'Wayne'); // Hello, Bruce Wayne

登录后复制

可以写成这种形式

curriedGreet = curry(greet);curriedGreet('Hello')('Bruce')('Wayne'); // Hello, Bruce Wayne

登录后复制

如何正确的使用?

正确的使用“柯里化”是因为某些curry函数在使用上更加灵活。Currying 在理论上很棒,但是在 JavaScript 中为每个参数调用一个函数会很累。

Ramda 的 curry函数可以让你curriedGreet像这样调用:

// greet requires 3 params: (greeting, first, last)// these all return a function looking for (first, last)curriedGreet('Hello');curriedGreet('Hello')();curriedGreet()('Hello')()();// these all return a function looking for (last)curriedGreet('Hello')('Bruce');curriedGreet('Hello', 'Bruce');curriedGreet('Hello')()('Bruce')();// these return a greeting, since all 3 params were honoredcurriedGreet('Hello')('Bruce')('Wayne');curriedGreet('Hello', 'Bruce', 'Wayne');curriedGreet('Hello', 'Bruce')()()('Wayne');

登录后复制

请注意,你可以选择一次性给出多个参数。此实现在编写代码时更有用。

如上所示,你可以在没有参数的情况下永远调用此函数,并且它将始终返回一个需要剩余参数的函数。

工作原理相同

const curry = (f, arr = []) => (...args) =>  ((a) => (a.length === f.length ? f(...a) : curry(f, a)))([...arr, ...args]);

登录后复制

让我们一起重构和欣赏它。

我还在debuggerChrome 开发人员工具中添加了一些语句来检查它。

curry = (originalFunction, initialParams = []) => {  debugger;  return (...nextParams) => {    debugger;    const curriedFunction = (params) => {      debugger;      if (params.length === originalFunction.length) {        return originalFunction(...params);      }      return curry(originalFunction, params);    };    return curriedFunction([...initialParams, ...nextParams]);  };};

登录后复制

开始

粘贴greet并curry进入您的控制台。然后进入curriedGreet = curry(greet)并开始疯狂。

在第 2 行暂停

1.png

检查我们看到的两个参数,originalFunction并且greet默认initialParams为空数组,因为我们没有提供它。移动到下一个断点,哦等等……就是这样。是的!curry(greet)只返回一个需要 3 个以上参数的新函数。在控制台中输入curriedGreet以查看我在说什么。

当你玩完这个之后,让我们变得更疯狂一点,然后做
sayHello = curriedGreet(‘Hello’).

在第 4 行暂停

2.png

在继续之前,在控制台中输入originalFunction和。initialParams请注意,即使我们在一个全新的函数中,我们仍然可以访问这两个参数?这是因为从父函数返回的函数享有其父函数的作用域。

继承

在父函数传递之后,他们将参数留给孩子使用。有点像现实生活中的继承。

curry最初给出originalFunction,initialParams然后返回一个“子”函数。这两个变量还没有被处理掉,因为也许那个孩子需要它们。如果他不这样做,那么这个范围就会被清理干净,因为当没有人提到你时,那就是你真正死去的时候。

好的,回到第 4 行……

3.png

检查nextParams并看到它是[‘Hello’]……一个数组?但我以为我们说curriedGreet(‘Hello’) ,不是curriedGreet([‘Hello’])!

正确:我们调用curriedGreet了 with ‘Hello’,但是多亏了rest 语法,我们变成 ‘Hello’了[‘Hello’].

是吗?!

curry是一个通用函数,可以提供 1、10 或 10,000,000 个参数,因此它需要一种方法来引用所有参数。使用类似的 rest 语法捕获一个数组中的每个参数,使curry’ 的工作更容易。

让我们跳到下debugger一条语句。

现在是第 6 行,但请稍等。

您可能已经注意到第 12 行实际上在debugger第 6 行的语句之前运行。如果不是,请仔细查看。我们的程序在第 5 行定义了一个调用函数curriedFunction,在第 12 行使用它,然后我们debugger在第 6 行点击了该语句。curriedFunction调用的是什么?

[...initialParams, ...nextParams];

登录后复制

呸呸呸。查看params第 5 行,您会看到[‘Hello’]. 两者initialParams和都是数组,所以我们使用方便的扩展运算符nextParams将它们展平并组合成一个数组。

这就是好事发生的地方。

5.png

第 7 行说“如果params和originalFunction长度相同,请greet使用我们的参数调用,我们就完成了。” 这使我想起…

JavaScript 函数也有长度

这就是curry它的魔力!这就是它决定是否要求更多参数的方式。

在 JavaScript 中,函数的 .length属性告诉你它需要多少个参数

greet.length; // 3iTakeOneParam = (a) => {};iTakeTwoParams = (a, b) => {};iTakeOneParam.length; // 1iTakeTwoParams.length; // 2复制代码

登录后复制

如果我们提供的和预期的参数匹配,我们很好,只需将它们交给原始函数并完成工作!

但是在我们的例子中,参数和函数长度是一样的。我们只提供了‘Hello’,所以params.length是 1,并且originalFunction.length是 3 因为greet需要 3 个参数:greeting, first, last。

那么接下来会发生什么?

好吧,由于该if语句的计算结果为false,代码将跳到第 10 行并重新调用我们的主curry函数。它重新接收greet,这一次,’Hello’并重新开始疯狂。

这就是递归,我的朋友们。

curry本质上是一个无限循环的自调用,参数饥渴的函数,直到他们的客人满了才会休息。热情好客。

6.png

回到第 2 行

与以前相同initialParams的参数,除了[‘Hello’]这次。再次跳过以退出循环。在控制台中输入我们的新变量,sayHello. 这是另一个函数,仍然期待更多参数,但我们正在变得更加温暖……

让我们把火调大sayHelloToJohn = sayHello(‘John’)。

我们又在第 4 行了,而且nextParams是[‘John’]。跳到第 6 行的下一个调试器并检查params:它是[‘Hello’, ‘John’]!?

7.png

为什么?

因为请记住,第 12 行说“嘿curriedFunction,他’Hello’上次和‘John’这次都给了我。把他们两个都带进这个阵法[…initialParams, …nextParams]。”

8.png

现在curriedFunction再次将length这些params与进行比较originalFunction,因为2

9.png

我们已经很接近了,让我们完成这一切,并得到完整的问候!

sayHelloToJohnDoe = sayHelloToJohn(‘Doe’)

我想我们知道接下来会发生什么。

10.png

11.png

12.png

结论

greet得到他的参数,curry停止循环,我们收到了我们的问候:Hello, John Doe.

多玩一些这个功能。尝试一次提供多个参数或不提供参数,随心所欲地疯狂。curry查看在返回预期输出之前必须递归多少次。

curriedGreet('Hello', 'John', 'Doe');curriedGreet('Hello', 'John')('Doe');curriedGreet()()('Hello')()('John')()()()()('Doe');

登录后复制

【相关视频教程推荐:web前端 】

以上就是一文快速了解JS中的柯里化(Currying)的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2702542.html

(0)
上一篇 2025年3月7日 19:25:14
下一篇 2025年3月7日 19:25:31

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 超实用的JavaScript调试技巧

    本篇文章给大家带来了关于javascript中的相关知识,其中主要介绍了javascript的调试技巧,包括了sources面板、设置断点等相关问题,希望对大家有帮助。 相关推荐:javascript视频教程 作为前端开发,我们会经常使用 …

    2025年3月7日 编程技术
    200
  • JavaScript中栈和堆的区别是什么

    区别:1、在内存操作中,栈由操作系统自动分配和释放,而堆由开发人员自主分配和释放;2、在数据结构中,栈是一种运算受限的线性表,只允许表的一端进行插入和删除操作,而堆是一种优先队列,会根据优先级找优先度最高的先执行。 本教程操作环境:wind…

    2025年3月7日
    200
  • JavaScript模块化编程规范之CommonJS、AMD、CMD、ES6

    本篇文章给大家带来了关于javascript中的相关知识,其中主要介绍了模块化编程规范,commonjs、amd、cmd以及es6的相关问题,希望对大家有帮助。 相关推荐:javascript学习教程 一、前言 AMD、CMD、Common…

    2025年3月7日
    200
  • javascript技巧之拆箱装箱和类型转换

    本篇文章给大家带来了关于javascript中的相关知识,其中主要介绍了拆箱装箱和类型转换的相关问题,装箱是指把基本数据类型转换为对应的引用类型的操作,下面就一起来看一下,希望对大家有帮助。 相关推荐:javascript教程 基本数据类型…

    2025年3月7日
    200
  • 详细介绍JavaScript怎么实现哈希表

    本篇文章给大家带来了关于javascript中的相关知识,其中主要介绍了关于javascript怎么实现哈希表的相关问题,对最终数据插入的数组进行整个结构的封装,得到的就是哈希表,希望对大家有帮助。 相关推荐:javascript学习教程 …

    2025年3月7日 编程技术
    200
  • 一起来聊聊JavaScript函数柯里化

    本篇文章给大家带来了关于javascript中的相关知识,其中主要介绍了javascript中函数柯里化的相关问题,柯里化是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术,希望对大家有帮助。…

    2025年3月7日
    200
  • es6中怎么将set转化为数组

    es6中将set转化为数组的方法:1、使用扩展运算符“…”,语法“[…set对象]”;2、使用Array.from()方法,语法“Array.from(set对象)”。 本教程操作环境:windows7系统、ECMA…

    2025年3月7日
    200
  • es6怎么判断数组是否含有相同的值

    判断方法:1、将数组转为Set集合,并使用size属性获取Set元素总数,语法“new Set(arr).size”;2、利用length属性获取数组元素总数;3、比较Set元素总数和数组元素总数是否相等,不相等则含有相同的值,反之则没有。…

    2025年3月7日
    200
  • 实例图文详解在JavaScript中实现队列

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了javascript实现队列的相关问题,描述队列数据结构,其具有的操作以及展示javascript中的队列实现,希望对大家有帮助。 相关推荐:javascript教程 1…

    2025年3月7日 编程技术
    200
  • 怎么快速掌握正则表达式?通过 AST 来学学正则语法!

    正则表达式是对字符串操作的一种逻辑公式,是在处理文本数据时的一项重要而复杂的技术。那么怎么快速掌握正则表达式?下面本篇文章推荐一种学习方法:通过 ast。希望对大家有所帮助! 字符串的处理基本都会用正则表达式,用它来做字符串的匹配、提取、替…

    2025年3月7日 编程技术
    200

发表回复

登录后才能评论