// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;add(1, 2, 3)(4) = 10;add(1)(2)(3)(4)(5) = 15;
function add() {
// 第一次执行时,定义一个数组专门用来存储所有的参数
var _args = Array.prototype.slice.call(arguments);
// 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
var _adder = function() {
_args.push(...arguments);
return _adder;
};
// 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;}add(1)(2)(3) // 6add(1, 2, 3)(4) // 10add(1)(2)(3)(4)(5) // 15add(2, 6)(1) // 9
// ES5
function curry(fn) { function _c(restNum, argsList) { return restNum === 0 ?
fn.apply(null, argsList) : function(x) { return _c(restNum - 1, argsList.concat(x));
};
} return _c(fn.length, []);
}
// ES6
const curry = fn => { const _c = (restNum, argsList) => restNum === 0 ?
fn(...argsList) : x => _c(restNum - 1, [...argsList, x]); return _c(fn.length, []);
}
/***************** 使用 *********************/var plus = curry(function(a, b) { return a + b;
});// ES6const plus = curry((a, b) => a + b);
plus(2)(4); // => 6
function currying(fn, ...rest1) {
return function(...rest2) {
return fn.apply(null, rest1.concat(rest2))
}
}
function curryingHelper(fn, len) { const length = len || fn.length // 第一遍运行length是函数fn一共需要的参数个数,以后是剩余所需要的参数个数
return function(...rest) { return rest.length >= length // 检查是否传入了fn所需足够的参数
? fn.apply(this, rest)
: curryingHelper(currying.apply(this, [fn].concat(rest)), length - rest.length) // 在通用currying函数基础上
}
}function sayHello(name, age, fruit) { console.log(`我叫 ${name},我 ${age} 岁了, 我喜欢吃 ${fruit}`) }
const betterShowMsg = curryingHelper(sayHello)
betterShowMsg('小衰', 20, '西瓜') // 我叫 小衰,我 20 岁了, 我喜欢吃 西瓜betterShowMsg('小猪')(25, '南瓜') // 我叫 小猪,我 25 岁了, 我喜欢吃 南瓜betterShowMsg('小明', 22)('倭瓜') // 我叫 小明,我 22 岁了, 我喜欢吃 倭瓜betterShowMsg('小拽')(28)('冬瓜') // 我叫 小拽,我 28 岁了, 我喜欢吃 冬瓜