溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS中的柯里化Currying怎么用

發(fā)布時間:2022-03-03 14:31:14 來源:億速云 閱讀:134 作者:小新 欄目:web開發(fā)

這篇文章主要為大家展示了“JS中的柯里化Currying怎么用”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“JS中的柯里化Currying怎么用”這篇文章吧。

柯里化將多參數(shù)函數(shù)轉換為一元(單參數(shù))函數(shù)。

柯里化函數(shù)一次接受多個參數(shù)。所以如果你有

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函數(shù)在使用上更加靈活。Currying 在理論上很棒,但是在 JavaScript 中為每個參數(shù)調(diào)用一個函數(shù)會很累。

Ramda 的 curry函數(shù)可以讓你curriedGreet像這樣調(diào)用:

// 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');

請注意,你可以選擇一次性給出多個參數(shù)。此實現(xiàn)在編寫代碼時更有用。

如上所示,你可以在沒有參數(shù)的情況下永遠調(diào)用此函數(shù),并且它將始終返回一個需要剩余參數(shù)的函數(shù)。

工作原理相同

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

讓我們一起重構和欣賞它。

我還在debuggerChrome 開發(fā)人員工具中添加了一些語句來檢查它。

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

開始

粘貼greetcurry進入您的控制臺。然后進入curriedGreet = curry(greet)并開始瘋狂。

在第 2 行暫停

JS中的柯里化Currying怎么用

檢查我們看到的兩個參數(shù),originalFunction并且greet默認initialParams為空數(shù)組,因為我們沒有提供它。移動到下一個斷點,哦等等……就是這樣。 是的!curry(greet)只返回一個需要 3 個以上參數(shù)的新函數(shù)。在控制臺中輸入curriedGreet以查看我在說什么。

當你玩完這個之后,讓我們變得更瘋狂一點,然后做
sayHello = curriedGreet('Hello').

在第 4 行暫停

JS中的柯里化Currying怎么用

在繼續(xù)之前,在控制臺中輸入originalFunction和。initialParams請注意,即使我們在一個全新的函數(shù)中,我們?nèi)匀豢梢栽L問這兩個參數(shù)?這是因為從父函數(shù)返回的函數(shù)享有其父函數(shù)的作用域。

繼承

在父函數(shù)傳遞之后,他們將參數(shù)留給孩子使用。有點像現(xiàn)實生活中的繼承。

curry最初給出originalFunction,initialParams然后返回一個“子”函數(shù)。這兩個變量還沒有被處理掉,因為也許那個孩子需要它們。如果他不這樣做,那么這個范圍就會被清理干凈,因為當沒有人提到你時,那就是你真正死去的時候。

好的,回到第 4 行……

JS中的柯里化Currying怎么用

檢查nextParams并看到它是['Hello']……一個數(shù)組?但我以為我們說curriedGreet(‘Hello’) ,不是curriedGreet(['Hello'])!

正確:我們調(diào)用curriedGreet了 with 'Hello',但是多虧了rest 語法,我們變成 'Hello'['Hello'].

是嗎?!

curry是一個通用函數(shù),可以提供 1、10 或 10,000,000 個參數(shù),因此它需要一種方法來引用所有參數(shù)。使用類似的 rest 語法捕獲一個數(shù)組中的每個參數(shù),使curry' 的工作更容易。

讓我們跳到下debugger一條語句。

現(xiàn)在是第 6 行,但請稍等。

您可能已經(jīng)注意到第 12 行實際上在debugger第 6 行的語句之前運行。如果不是,請仔細查看。我們的程序在第 5 行定義了一個調(diào)用函數(shù)curriedFunction,在第 12 行使用它,然后我們debugger在第 6 行點擊了該語句。curriedFunction調(diào)用的是什么?

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

呸呸呸。查看params第 5 行,您會看到['Hello']. 兩者initialParams和都是數(shù)組,所以我們使用方便的擴展運算符nextParams將它們展平并組合成一個數(shù)組。

這就是好事發(fā)生的地方。

JS中的柯里化Currying怎么用

第 7 行說“如果paramsoriginalFunction長度相同,請greet使用我們的參數(shù)調(diào)用,我們就完成了?!?這使我想起…

JavaScript 函數(shù)也有長度

這就是curry它的魔力!這就是它決定是否要求更多參數(shù)的方式。

在 JavaScript 中,函數(shù)的 .length屬性告訴你它需要多少個參數(shù)。

greet.length; // 3

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

iTakeOneParam.length; // 1
iTakeTwoParams.length; // 2復制代碼

如果我們提供的和預期的參數(shù)匹配,我們很好,只需將它們交給原始函數(shù)并完成工作!

但是在我們的例子中,參數(shù)和函數(shù)長度是一樣的。我們只提供了‘Hello’,所以params.length是 1,并且originalFunction.length是 3 因為greet需要 3 個參數(shù):greeting, first, last

那么接下來會發(fā)生什么?

好吧,由于該if語句的計算結果為false,代碼將跳到第 10 行并重新調(diào)用我們的主curry函數(shù)。它重新接收greet,這一次,'Hello'并重新開始瘋狂。

這就是遞歸,我的朋友們。

curry本質(zhì)上是一個無限循環(huán)的自調(diào)用,參數(shù)饑渴的函數(shù),直到他們的客人滿了才會休息。熱情好客。

JS中的柯里化Currying怎么用

回到第 2 行

與以前相同initialParams的參數(shù),除了['Hello']這次。再次跳過以退出循環(huán)。在控制臺中輸入我們的新變量,sayHello. 這是另一個函數(shù),仍然期待更多參數(shù),但我們正在變得更加溫暖......

讓我們把火調(diào)大sayHelloToJohn = sayHello('John')。

我們又在第 4 行了,而且nextParams['John']。跳到第 6 行的下一個調(diào)試器并檢查params:它是['Hello', 'John']!?

JS中的柯里化Currying怎么用

為什么?

因為請記住,第 12 行說“嘿curriedFunction,他'Hello'上次和‘John’這次都給了我。把他們兩個都帶進這個陣法[...initialParams, ...nextParams]?!?/p>

JS中的柯里化Currying怎么用

現(xiàn)在curriedFunction再次將length這些params與進行比較originalFunction,因為2 < 3我們移動到第 10 行并curry再次調(diào)用!當然,我們傳遞greet了我們的 2 個參數(shù),['Hello', 'John']

JS中的柯里化Currying怎么用

我們已經(jīng)很接近了,讓我們完成這一切,并得到完整的問候!

sayHelloToJohnDoe = sayHelloToJohn('Doe')

我想我們知道接下來會發(fā)生什么。

JS中的柯里化Currying怎么用

JS中的柯里化Currying怎么用

JS中的柯里化Currying怎么用

結論

greet得到他的參數(shù),curry停止循環(huán),我們收到了我們的問候:Hello, John Doe.

多玩一些這個功能。嘗試一次提供多個參數(shù)或不提供參數(shù),隨心所欲地瘋狂。curry查看在返回預期輸出之前必須遞歸多少次。

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

以上是“JS中的柯里化Currying怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI