在說明柯里化以前,首先須要理解高階函數的定義javascript
高階函數是指以函數做爲參數的函數,僞代碼能夠理解爲java
function higherOrderFunction(fn) { console.log(typeof fn) // "function" }
在計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數且返回結果的新函數的技術。數組
從定義中咱們能夠對柯里化的步驟作一個簡要的歸納:閉包
根據如上定義,能夠用以下僞碼錶示柯里化的使用app
// 實現參數分步輸入 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 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
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
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