// 函数柯里化:f(x, y, z) => h(x)(y)(z)
// 第一步:加法运算柯里化
// add(a, b, c) => curryAdd(a)(b)(c)
let sum = 0;
function add() {
sum += Array.from(arguments).reduce((x, y) => x + y);
add.toString = () => sum; // console.log时实际调用的是Function.toString()
return add;
}
// 第二步:利用闭包实现纯函数式的柯里化
function curryAdd() {
// 第一次调用时,就要对参数求和并保存到total中
let total = Array.from(arguments).reduce((x, y) => x + y);
// 利用闭包特性,保存total
const _add = function () { // 注意此处不能写成箭头函数
total += Array.from(arguments).reduce((x, y) => x + y);
return _add;
}
_add.toString = () => total;
return _add;
}
// 第三步:把对参数的操作放在最后
function curryAddAdvanced() {
// 把参数保存到一个数组里
const arr = Array.from(arguments);
// 利用闭包特性,保存total
const _add = function () { // 注意此处不能写成箭头函数
arr.push(...Array.from(arguments));
return _add;
}
_add.toString = () => Array.from(arr).reduce((x, y) => x + y);
return _add;
}
// 测试加法运算柯里化
console.log("add", add(1, 2, 3)(4)(6, 7))
console.log("curryAdd", curryAdd(1)(2, 3)(4)(6, 7), curryAdd(1, 2, 3)(4)(6, 7));
console.log("curryAddAdvanced", curryAddAdvanced(1)(2, 3)(4)(6, 7), curryAddAdvanced(1, 2, 3)(4)(6, 7));
// 第四步:将柯里化操作抽象为封装函数
function fnToCurry(fn) {
const curry = function () {
const arr = [];
// 第一次调用时,把参数保存到一个数组里
arr.push(...Array.from(arguments));
// 利用闭包特性,保存total
const _fn = function () { // 注意此处不能写成箭头函数
arr.push(...Array.from(arguments));
return _fn;
}
_fn.toString = () => fn(...arr);
return _fn;
}
return curry;
}
// 测试柯里化封装函数
// 测试1:乘法运算
function f1() {
return Array.from(arguments).reduce((x, y) => x + y);
}
const f2 = fnToCurry(f1);
console.log("柯里化", f2(1, 2, 3), f2(1)(2, 3), f2(1)(2)(3));
// 延迟执行
// 假设当传入参数包含"exec"时,再执行
// 如fn(a)(b)(c)("exec"),当最后再执行
function fnToDelayCurry(fn) {
const arr = [];
const curry = function () {
// 第一次调用时,把参数保存到一个数组里
arr.push(...Array.from(arguments));
// 利用闭包特性,保存total
const _fn = function () { // 注意此处不能写成箭头函数
// 当输入的参数中有exec标志时,立即执行
// 这里包含exec的参数不保存到arr中,若要保存把else中的push挪到外层即可
if (Array.from(arguments).indexOf("exec") > -1) {
_fn.toString = () => fn(...arr);
} else {
_fn.toString = Function.toString;
arr.push(...Array.from(arguments));
}
return _fn;
}
return _fn;
}
return curry;
}
function delayFn() {
const args = Array.from(arguments);
return args.join("~");
}
console.log("不会执行函数", fnToDelayCurry(delayFn)(1)(2)(3)(4, 5)); // 这里打印的是函数
console.log("最后执行函数", fnToDelayCurry(delayFn)(1)(2)(3)(4, 5)("exec")); // 这里真正执行
console