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