這是我參與8月更文挑戰的第10天,活動詳情查看:8月更文挑戰前端
柯里化(Currying)是把接受多個參數的函數轉變爲單一參數的函數,而且返回接受餘下的參數且返回結果的新函數的技術。面試
簡單來講:segmentfault
即:經過將多個參數換成一個參數,每次運行返回新函數的技術markdown
// 普通的 add 函數
function add (a, b) {
return a + b;
}
add(1, 2);
複製代碼
// 柯里化函數
function curryingAdd (x) {
return function(y) {
return x + y;
}
}
curryingAdd(x)(y);
複製代碼
// 校驗數字
let numberReg = /[0-9]+/g;
// 校驗小寫字母
let stringReg = /[a-z]+/g;
// currying 後
function curryingCheck(reg) {
return function(txt) {
return reg.test(txt);
}
}
let checkNumber = curryingCheck(numberReg);
let checkString = curryingCheck(stringReg);
console.log(checkNumber('13888888888')); // true
console.log(checkString('jsliang')); // true
複製代碼
add(1)(2)(3)
// 實現一個 add 方法,使計算結果可以知足如下預期
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
複製代碼
function add () {
const numberList = Array.from(arguments);
// 進一步收集剩餘參數
const calculate = function() {
numberList.push(...arguments);
return calculate;
}
// 利用 toString 隱式轉換,最後執行時進行轉換
calculate.toString = function() {
return numberList.reduce((a, b) => a + b, 0);
}
return calculate;
}
// 實現一個 add 方法,使計算結果可以知足如下預期
console.log(add(1)(2)(3)); // 6
console.log(add(1, 2, 3)(4)); // 10;
console.log(add(1)(2)(3)(4)(5)); // 15;
console.log(add(1)(2)(3)(4)(5, 6, 7)); // 28
複製代碼
function foo(...args) {
console.log(args[0]);
return 'foo';
}
function bar(...args) {
console.log(args[0]);
return 'bar';
}
function baz(...args) {
console.log(args[0]);
return 'baz';
}
function compose() {
// 閉包元素 - 函數列表
const list = Array.from(arguments);
// 閉包元素 - 函數列表執行位置
let index = -1;
// 閉包元素 - 上一個函數的返回
let prev = '';
// 返回閉包函數
const doNext = function() {
index++; // 索引值累加
// 一開始沒有上一個元素時,獲取第二個括號的值
if (!prev) {
prev = arguments[0];
}
// 設置前一個結果爲當前函數返回
prev = list[index](prev);
// 遞歸調用
if (index < list.length - 1) {
doNext(index + 1);
}
};
// 第一次返回閉包函數
return doNext;
}
compose(foo, bar, baz)('start');
複製代碼