Home  >  Article  >  Web Front-end  >  Quickly understand Currying in JS in one article

Quickly understand Currying in JS in one article

青灯夜游
青灯夜游forward
2022-02-25 11:04:151688browse

This article will give you a quick understanding of Currying in Javascript. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

Quickly understand Currying in JS in one article

# Currying converts a multi-parameter function into a unary (single parameter) function. [Related recommendations: javascript learning tutorial]

Curried functionaccepts multiple parameters at one time. So if you have

greet = (greeting, first, last) => `${greeting}, ${first} ${last}`;

greet('Hello', 'Bruce', 'Wayne'); // Hello, Bruce Wayne

, you can write it in this form

curriedGreet = curry(greet);

curriedGreet('Hello')('Bruce')('Wayne'); // Hello, Bruce Wayne

How to use it correctly?

The correct use of "currying" is because some

curry functions are more flexible in use. Currying is great in theory, but calling a function for every parameter in JavaScript can be tiring.

Ramda's curry function allows you to curriedGreet call it like this:

// 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 honored
curriedGreet('Hello')('Bruce')('Wayne');
curriedGreet('Hello', 'Bruce', 'Wayne');
curriedGreet('Hello', 'Bruce')()()('Wayne');

Please note that you can select once Multiple parameters are given. This implementation is more useful when writing code.

As shown above, you can call this function forever without arguments, and it will always return a function that requires the remaining arguments.

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

Let’s refactor and appreciate it together.

I also added some statements in

debuggerChrome Developer Tools to check it.

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]);
  };
};

Start

Paste

greet and curry into your console. Then go into curriedGreet = curry(greet) and start going crazy.

Pause on line 2

Quickly understand Currying in JS in one article

Check the two parameters we see,

originalFunctionandgreetDefaultinitialParams is an empty array because we did not provide it. Move to the next breakpoint and oh wait...that's it. Yes! curry(greet)Only returns a new function that requires more than 3 parameters. Type curriedGreet in the console to see what I'm talking about.

When you're done playing with this, let's get a little crazier and do


sayHello = curriedGreet('Hello').

Pause on line 4

Quickly understand Currying in JS in one article

Before continuing, enter

originalFunction and in the console. initialParams Notice that even though we are in a brand new function, we still have access to these two parameters? This is because a function returned from a parent function shares the scope of its parent function.

Inheritance

After the parent function is passed, they leave the parameters to the child. Kind of like inheritance in real life.

curry Initially gives originalFunction, initialParams and then returns a "child" function. These two variables have not been disposed yet, because maybe the child needs them. If he doesn't, then the range will be cleared, because when no one mentions you, that's when you truly die.

Okay, back to line 4...

Quickly understand Currying in JS in one article

Check

nextParams and see that it is ['Hello']...an array? But I thought we said curriedGreet(‘Hello’), not curriedGreet(['Hello’])!

Correct: We called

curriedGreet with 'Hello', but thanks to the rest syntax , we became 'Hello'['Hello'].

Really? !

curry is a general function that can be supplied with 1, 10, or 10,000,000 arguments, so it needs a way to reference all arguments. Capture each parameter in an array using rest-like syntax to make curry's job easier.

Let’s jump to the next

debugger statement.

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

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

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

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

这就是好事发生的地方。

Quickly understand Currying in JS in one article

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

JavaScript 函数也有长度

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

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

greet.length; // 3

iTakeOneParam = (a) => {};
iTakeTwoParams = (a, b) => {};

iTakeOneParam.length; // 1
iTakeTwoParams.length; // 2复制代码

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

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

那么接下来会发生什么?

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

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

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

Quickly understand Currying in JS in one article

回到第 2 行

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

让我们把火调大sayHelloToJohn = sayHello('John')

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

Quickly understand Currying in JS in one article

为什么?

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

Quickly understand Currying in JS in one article

现在curriedFunction再次将length这些params与进行比较originalFunction,因为2 我们移动到第 10 行并<code>curry再次调用!当然,我们传递greet了我们的 2 个参数,['Hello', 'John']

Quickly understand Currying in JS in one article

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

sayHelloToJohnDoe = sayHelloToJohn('Doe')

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

Quickly understand Currying in JS in one article

1Quickly understand Currying in JS in one article

1Quickly understand Currying in JS in one article

结论

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

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

curriedGreet(&#39;Hello&#39;, &#39;John&#39;, &#39;Doe&#39;);
curriedGreet(&#39;Hello&#39;, &#39;John&#39;)(&#39;Doe&#39;);
curriedGreet()()(&#39;Hello&#39;)()(&#39;John&#39;)()()()()(&#39;Doe&#39;);

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

The above is the detailed content of Quickly understand Currying in JS in one article. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete