摘要:從定義中我們可以對柯里化的步驟做一個簡要的概括存在一個函數(shù),接受一個函數(shù)作為參數(shù),并返回一個函數(shù)。若相等,則將參數(shù)放入源函數(shù)并返回執(zhí)行結(jié)果。
柯里化 高階函數(shù)
在說明柯里化之前,首先需要理解高階函數(shù)的定義
高階函數(shù)是指以函數(shù)作為參數(shù)的函數(shù),偽代碼可以理解為
function higherOrderFunction(fn) { console.log(typeof fn) // "function" }定義
在計算機科學(xué)中,柯里化(Currying)是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù),并且返回接受余下的參數(shù)且返回結(jié)果的新函數(shù)的技術(shù)。
從定義中我們可以對柯里化的步驟做一個簡要的概括:
存在一個函數(shù)currying,接受一個函數(shù)source作為參數(shù),并返回一個函數(shù)tmpCurrying。
tmpCurrying接收單一參數(shù),并再次返回一個tmpCurrying,直到所有tmpCurrying接收的參數(shù)和等于source函數(shù)所需的形參數(shù)量。
將tmpCurrying收到的所有單一參數(shù)按順序放入source函數(shù),并執(zhí)行,以獲得結(jié)果。
實際應(yīng)用 使用形式根據(jù)如上定義,可以用如下偽碼表示柯里化的使用
參數(shù)分步輸入
// 實現(xiàn)參數(shù)分步輸入 function sum(a,b,c) { return [...args].reduce((pre,next) => (pre + next)); } // 存在一個函數(shù)currying const curriedSum = currying(sum); curriedSum(1)(2)(3); // 6; curriedSum(1, 2)(3); // 6; curriedSum(1, 2, 3); // 6;
函數(shù)抽象,高階函數(shù)封裝
// 用于函數(shù)抽象,高階函數(shù)封裝等 // 存在如下功能函數(shù) function isPhone(number) { return /^1[34578]d{9}$/.test(number); } function isMail(mail) { return /^(w)+(.w+)*@(w)+((.w+)+)$/.test(mail); } /* 可以講上面兩個函數(shù)抽象為 regString.test(targetString); */ function check(reg, target) { return reg.test(target); } /* 但是每次使用時仍然需要輸入正則作為參數(shù),于是考慮利用柯里化的功能,將函數(shù)參數(shù)拆為兩部分,正則 + 校驗對象 假設(shè)存在一個柯里化函數(shù)currying(fn, reg) */ export const checkPhone = currying(check, /^1[34578]d{9}$/); export const checkMail = currying(check, /^(w)+(.w+)*@(w)+((.w+)+)$/); /* checkPhone和checkMail此時皆是只需要一個參數(shù)targetString的函數(shù) 使用時只需直接使用即可 */ checkPhone(13111111111); // true;柯里化實現(xiàn)
想要實現(xiàn)柯里化函數(shù),需要掌握以下知識點
閉包:內(nèi)層函數(shù)可以訪問外層函數(shù)的變量
Function.length: 函數(shù)的length屬性表示其聲明時的形參數(shù)量
arguments: 類數(shù)組arguments表示函數(shù)調(diào)用時的實參列表(或直接使用參數(shù)解構(gòu),獲取實參數(shù)組,推薦此種。原因:arguments只是類數(shù)組,沒有數(shù)組方法,不方便使用,需要用結(jié)構(gòu)或apply等方式將其轉(zhuǎn)化為數(shù)組)
實現(xiàn)解析利用閉包將每次多帶帶輸入的參數(shù)存入外層函數(shù)currying的數(shù)組變量args中。
校驗當(dāng)前args的長度與被封裝函數(shù)的形參數(shù)量是否相等,不相等則繼續(xù)返回接受參數(shù)的中間函數(shù)。
若相等,則將參數(shù)放入源函數(shù)并返回執(zhí)行結(jié)果。
實現(xiàn)1---每次只接受一個參數(shù)function currying(src) { // 記錄源函數(shù)的形參長度 const length = src.length; // 參數(shù)列表 const argsPool = []; return function tmpFn (arg) { // 將參數(shù)推入?yún)?shù)池 argsPool.push(arg); // 長度判斷 if (length > argsPool.length) { return tmpFn; } else { const res = src(...argsPool); argsPool = []; return res; } } } function sum(a, b, c, d, e, f) { return [...arguments].reduce((pre, next) => (pre + next)); } const _sum = currying(sum); _sum(1)(2)(3)(4)(5)(6); // 21實現(xiàn)2:每次接受若干個參數(shù)
function currying(src, ...args) { // 記錄源函數(shù)的形參長度 const length = src.length; // 參數(shù)列表 const argsPool = [...args]; return function tmpFn (...args) { // 將參數(shù)推入?yún)?shù)池 argsPool.push(...args); // 長度判斷 if (length > argsPool.length) { return tmpFn; } else { const res = src(...argsPool); argsPool = []; return res; } } } function sum(a, b, c, d, e, f) { return [...arguments].reduce((pre, next) => (pre + next)); } const _sum = currying(sum); _sum(1)(2)(3)(4)(5)(6); // 21 _sum(1, 2, 3, 4)(5, 6); // 21實現(xiàn)3:不規(guī)定參數(shù)個數(shù),以無參數(shù)傳入為循環(huán)終止標(biāo)識
function currying(src, ...args) { // 參數(shù)列表 let argsPool = [...args]; return function tmpFn (...args) { if (args.length > 0) { argsPool.push(...args); return tmpFn; } else { const res = src(...argsPool); argsPool = []; return res; } } } function sum(...args) { return args.reduce((pre, next) => (pre + next)); } const _sum = currying(sum); _sum(1,2,3)(4,5)(); // 15 _sum(1,2)(); // 3
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102321.html
摘要:柯里化通用式上面的柯里化函數(shù)沒涉及到高階函數(shù),也不具備通用性,無法轉(zhuǎn)換形參個數(shù)任意或未知的函數(shù),我們接下來封裝一個通用的柯里化轉(zhuǎn)換函數(shù),可以將任意函數(shù)轉(zhuǎn)換成柯里化。 showImg(https://segmentfault.com/img/remote/1460000018998373); 閱讀原文 前言 在 JavaScript 中,柯里化和反柯里化是高階函數(shù)的一種應(yīng)用,在這之前...
摘要:函數(shù)柯里化是把支持多個參數(shù)的函數(shù)變成接收單一參數(shù)的函數(shù),并返回一個函數(shù)能接收處理剩余參數(shù),而反柯里化就是把參數(shù)全部釋放出來。但在一些復(fù)雜的業(yè)務(wù)邏輯封裝中,函數(shù)柯里化能夠為我們提供更好的應(yīng)對方案,讓我們的函數(shù)更具自由度和靈活性。 showImg(https://segmentfault.com/img/bVburN1?w=800&h=600); 柯里化(Curring, 以邏輯學(xué)家Has...
摘要:作為函數(shù)式編程語言,帶來了很多語言上的有趣特性,比如柯里化和反柯里化。在一些函數(shù)式編程語言中,會定義一個特殊的占位變量。個人理解不知道對不對延遲執(zhí)行柯里化的另一個應(yīng)用場景是延遲執(zhí)行。不斷的柯里化,累積傳入的參數(shù),最后執(zhí)行。作為函數(shù)式編程語言,JS帶來了很多語言上的有趣特性,比如柯里化和反柯里化。 這里可以對照另外一篇介紹 JS 反柯里化 的文章一起看~ 1. 簡介 柯里化(Currying)...
摘要:作為函數(shù)式編程語言,帶來了很多語言上的有趣特性,比如柯里化和反柯里化。個人理解不知道對不對延遲執(zhí)行柯里化的另一個應(yīng)用場景是延遲執(zhí)行。不斷的柯里化,累積傳入的參數(shù),最后執(zhí)行。 作為函數(shù)式編程語言,JS帶來了很多語言上的有趣特性,比如柯里化和反柯里化。 這里可以對照另外一篇介紹 JS 反柯里化 的文章一起看~ 1. 簡介 柯里化(Currying),又稱部分求值(Partial Evalu...
摘要:如果你對函數(shù)式編程有一定了解,函數(shù)柯里化是不可或缺的,利用函數(shù)柯里化,可以在開發(fā)中非常優(yōu)雅的處理復(fù)雜邏輯。同樣先看簡單版本的方法,以方法為例,代碼來自高級程序設(shè)計加強版實現(xiàn)上面函數(shù),可以換成任何其他函數(shù),經(jīng)過函數(shù)處理,都可以轉(zhuǎn)成柯里化函數(shù)。 我們經(jīng)常說在Javascript語言中,函數(shù)是一等公民,它們本質(zhì)上是十分簡單和過程化的??梢岳煤瘮?shù),進(jìn)行一些簡單的數(shù)據(jù)處理,return 結(jié)果,...
摘要:函數(shù)被轉(zhuǎn)化之后得到柯里化函數(shù),能夠處理的所有剩余參數(shù)。因此柯里化也被稱為部分求值。那么函數(shù)的柯里化函數(shù)則可以如下因此下面的運算方式是等價的。而這里對于函數(shù)參數(shù)的自由處理,正是柯里化的核心所在。額外知識補充無限參數(shù)的柯里化。 showImg(https://segmentfault.com/img/remote/1460000008493346); 柯里化是函數(shù)的一個比較高級的應(yīng)用,想要...
閱讀 3064·2021-11-18 10:02
閱讀 3333·2021-11-02 14:48
閱讀 3395·2019-08-30 13:52
閱讀 558·2019-08-29 17:10
閱讀 2087·2019-08-29 12:53
閱讀 1409·2019-08-29 12:53
閱讀 1031·2019-08-29 12:25
閱讀 2167·2019-08-29 12:17