function adds(a, b, c) { return a + b + c } function currying(fn, length){ length = length || fn.length; // 第一次调用获取函数 fn 参数的长度,后续调用获取 fn 剩余参数的长度 return function(){ var args = [].slice.call(arguments) // currying返回函数接受的参数 if (args.length < length) { // 判断参数的长度是否小于 fn 剩余参数需要接收的长度 return curry(fn.bind(this, ...args), length - args.length) // 递归 currying 函数,新的 fn 为 bind 返回的新函数(bind 绑定了 ...args 参数,未执行),新的 length 为 fn 剩余参数的长度 }else { return fn.call(this, ...args) // 执行 fn 函数,传入新函数的参数 } } } var addCurry = currying(adds);// 极简版 const currying = fn => judge = (...args) => args.length >= fn.length ? fn(...args) : (...arg) => judge(...args, ...arg) var addCurry = currying(adds); addCurry(2)(3)(4) // 9 addCurry(2, 3)(4) // 9 addCurry(2, 3, 4) // 9 addCurry(2)(3, 4) // 9// 其他版本 function add() { let data = [].concat(Array.prototype.slice.call(arguments)) function tmp() { // 使用闭包 data = data.concat(Array.prototype.slice.call(arguments)) return tmp; } tmp.valueOf = function () { return data.reduce(((source, item) => source + item), 0); } tmp.toString = function () { return data.reduce(((source, item) => source + item), 0); } return tmp } add(1) // 1 add(1,4)(2); // 7 add(1)(2, 5)(3)// 11 add(1,5,6)(2,5)(3)(4, 4) // 30