第 84 题:请实现一个 add 函数,满足以下功能

发布于 2022-07-06 20:03:17 字数 130 浏览 1068 评论 57

add(1); 	// 1
add(1)(2);  	// 3
add(1)(2)(3);  // 6
add(1)(2, 3);   // 6
add(1, 2)(3);   // 6
add(1, 2, 3);   // 6

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(57

幻想少年梦_ 2022-05-04 13:56:00

为什么console的时候不会自动调用 toString方法呢,上面的答案在我的chrome控制台里返回的都是函数

谜兔 2022-05-04 13:56:00
function add(...args1) {
    let x = args1.reduce((c,r)=>{return c+r},0)
    console.log(x)
    return  function(...args2){
            return add(...args2,x);
    };
}
add(1,2)(2)(1,3,4)

可以实现连续不定参数的调用,返回参数和

吃→可爱长大的 2022-05-04 13:56:00
function add () {
  let sum
  let arg = [].concat(...arguments)
  const fn = function () {
    arg = arg.concat(...arguments)
    sum = arg.reduce((pre, next) => pre + next)
    return fn
  }
  fn.toString = function () {
    return sum
  }
  return fn()
}
console.log('//' + add(1, 2)(3)()(4, 5, 6))
留一抹残留的笑 2022-05-04 13:56:00
 function addFn(...args) {
        return args.reduce((acc, cur) => acc + cur)
    }

    function currying(fn) {
        let args = []

        return function demo(...arg) {
            console.log(args);
            if (arg) {
                args = [...args, ...arg]
                return demo
            } else {
                return fn.apply(this, args)
            }
        }
    }

    const add = currying(addFn)
    console.log(add(1)(2)(3)());
    console.log(add(1)(2,3));
怎樣才叫好 2022-05-04 13:56:00

 var twoSum = function(nums, target) {
    const map = {}

    for (let i = 0 ;i < nums.length; i ++ ){
        if(map[target - nums[i] ] >= 0) {
            return [map[target - nums[i]],i]
        }
        map[nums[i]] = i;   
    }
};

七婞 2022-05-04 13:56:00

为什么console的时候不会自动调用 toString方法呢,上面的答案在我的chrome控制台里返回的都是函数

我也遇到了类似的问题,toString的方案在新版的Chrome(我的版本是98)似乎不起作用,打印出来的是一个函数,需要显式调用才能返回结果

黑色毁心梦 2022-05-04 13:56:00
function add(a) {
    var curSum = a;
    function res(b) {
        curSum += b
        return res
    }
    res.toString = function () {
        return curSum
    }
    return res
}
江湖彼岸 2022-05-04 13:56:00

建议把题目描述清楚

过期以后 2022-05-04 13:55:59

如果要做成高阶函数以便支持任意迭代器,累加器的初始值设定要麻烦一点
尤其是考虑到任意长度输入和空输入,要多一些判断逻辑。

写了一个支持以上所有特性的

const curryReducer = (fn) => {
  return (...args) => {
    let runned = false;
    const chain = (...args) => {
      if (!args.length) return chain;
      chain.acc = (runned ? [chain.acc] : []).concat(args).reduce(fn);
      !runned && (runned = true);
      return chain;
    };
    chain.acc = undefined;
    chain.toString = () => chain.acc;
    return chain(...args);
  };
};
// * ---------------- simple add function

const add = curryReducer((a, e) => a + e);

console.log('' + add(1, 2, 3)()(4, 5)(6)(7)(8, 9, 10));
const method = {
  add: (a, e) => a + e,
  minus: (a, e) => a - e,
  times: (a, e) => a * e,
  devide: (a, e) => a / e,
};
Object.values(method).forEach((e) => {
  console.log('batch test -------------- method is: ', e);
  const chainFn = curryReducer(e);
  console.log('' + chainFn());
  console.log('' + chainFn(6));
  console.log('' + chainFn(6, 2));
  console.log('' + chainFn(6)(2));
  console.log('' + chainFn()(6)(2));
  console.log('' + chainFn(6, 2, 3));
  console.log('' + chainFn(6, 2)(3));
  console.log('' + chainFn(6)(2)(3));
});
左秋 2022-05-04 13:55:59
function add(...a) {
    let sum = a.reduce((p, n) => p + n);

    function next(...b) {
        let _sum = b.reduce((p, n) => p + n);
        sum = sum + _sum;
        return next;
    }

    next.toString = function () {
        return sum;
    };

    return next;
}
○愚か者の日 2022-05-04 13:55:59
function currying(fn, length) {
  length = length || fn.length; 	// 注释 1
  return function (...args) {			// 注释 2
    return args.length >= length	// 注释 3
    	? fn.apply(this, args)			// 注释 4
      : currying(fn.bind(this, ...args), length - args.length) // 注释 5
  }
}
const sum = function(t,y,u){
    let args = [].slice.call(arguments)
    return args.reduce((a, b) => a + b)
} ;
    const add = currying(sum);
    console.log(add(1,2)(2)(9)) ;  	// Uncaught TypeError: add(...)(...) is not a function
请问这个调用这个柯里化函数sum中的形参还要自己手动补吗?
我看这个形参少于实际调用add函数时就会报错,还是我调用的方式错了呢?
@yygmind
够运- 2022-05-04 13:55:59

@wjryours sum 函数定义的参数长度为 3,调用时参数为 4,所以问题出在这里

俏︾媚 2022-05-04 13:55:59

@wjryours sum 函数定义的参数长度为 3,调用时参数为 4,所以问题出在这里

柯里化生成的 add 函数若是存储的形参个数达不到定义的参数长度, 则是返回 [Function]

那么如题 add(1) ==>1 , add(1)(2) ==> 3 则不是没有实现吗

不乱于心 2022-05-04 13:55:59

@wjryours sum 函数定义的参数长度为 3,调用时参数为 4,所以问题出在这里

柯里化生成的 add 函数若是存储的形参个数达不到定义的参数长度, 则是返回 [Function]

那么如题 add(1) ==>1 , add(1)(2) ==> 3 则不是没有实现吗

我想表达的就是这个意思,按照你这个写法那些基本的功能都通过不了,可以解答一下吗@yygmind

夕嗳→ 2022-05-04 13:55:59

@wjryours sum 函数定义的参数长度为 3,调用时参数为 4,所以问题出在这里

柯里化生成的 add 函数若是存储的形参个数达不到定义的参数长度, 则是返回 [Function]
那么如题 add(1) ==>1 , add(1)(2) ==> 3 则不是没有实现吗

我想表达的就是这个意思,按照你这个写法那些基本的功能都通过不了,可以解答一下吗@yygmind

我觉得题目出的不好(描述有歧义)。
我的理解里,题目本身和柯里化是有差异的,
题目更像是迭代器而不是柯里化

如果是柯里化,那么缺少参数的时候是等待所有参数到齐则再开始进行运算,并返回计算结果。
(因为不是所有方法都像 add 一样简单,能支持部分参数计算,不然因为缺少参数,计算逻辑报错了怎么办?)
参数不足的时候返回一个中间 function,以便继续调用。

至于直接能读到(toString),这是一个 trick。
对于柯里化这个高阶方法来说,我觉得不应该一起实现。
就像我说的,是应该等参数到齐再计算(固定参数 function 的 length),
可以参考一下 lodash 或者 ramda 里的 curry

至于如何实现题目本身
(任意长度也能返回计算结果,也就是说,调用一次执行一次)
(像我上面说的,更像是实现一个迭代器,add 只是一个算子)
可以参考一下我的答案
#134 (comment)
Inspired by @CoffeeWorm
#134 (comment)

这样的小城市 2022-05-04 13:55:59
const curry = fn => {
    const len = fn.length;
    return function curried(...args) {
        if (args.length === len) {
            return fn.apply(null, args);
        }
        return (..._args) => {
            return curried.apply(null, [...args, ..._args]);
        };
    };
};

const sum = (x, y, z) => x + y + z;
const add = curry(sum);

// 6
add(1, 2, 3);

// 6
add(1,2)(3);

// 6
add(1)(2,3);

// 6
add(1)(2)(3);
何处潇湘 2022-05-04 13:55:59
 // 第一步,先实现加和运算

            var add = function (a, b) {
                return a + b;
            }

            var currying = function (fn, defineVal = 0) {
                return function (...args) { // 第一次调用的是这个函数
                    // 每次执行前先进行和的初始化
                    var sum = defineVal;

                    function func(...argts) { // 第二次之后调用的是这个函数
                        if (args.length === 0) {
                            return func.toString();
                        } else {
                            argts.unshift(sum);
                            sum = argts.reduce(fn);
                            return func;
                        }
                    }
                    func.toString = () => sum;
                    return func(...args);
                }
            }

            var add = currying(add);
            console.info(add(1)); // => 1
            console.info(add(1)(2)); // => 3
            console.info(add(1)(2)(3)); // => 6
            console.info(add(1, 2)(3)); // => 6
            console.info(add(1)(2, 3)); // => 6
            console.info(add(1, 2, 3)); // => 6
            console.info(add(1, 2, 3)(4)); // => 10
若无相欠,怎会相见 2022-05-04 13:55:59
function add(...x) {
			var sum = x.reduce((a,b)=>a+b,0)
			var tmp = function(...y) {
				sum =sum+y.reduce((a,b)=>a+b,0)
				return tmp;
			};
			tmp.toString = function() {
				return sum;
			};
			return tmp;
		}
		
		console.log(+add(1)(2)(3))   // 6
		console.log(+add(1)(2,3))    // 6
		console.log(+add(1,2)(3))    // 6
		console.log(+add(1)(2)(3,4))   //10
		
		
		add(1)(2)(3).valueOf
		//ƒ valueOf() { [native code] }
		add(1)(2)(3).valueOf()
		//ƒ 6
		+add(1)(2)(3).valueOf()
		//6
		+""+add(1)(2)(3).valueOf()
		//6
	</script>
无言温柔 2022-05-04 13:55:59

`

function add() {

    var sum = function (arr) {
        var curSum = 0;
        for (var i = 0; i < arr.length; i++) {
            var obj = arr[i];
            if(obj){
                curSum = curSum + obj;
            }
        }
        return curSum;
    };

    var result = function () {
        var xx = Array.from(arguments);
        xx.push(result._lastSum);
        return add.apply({},xx);
    };

    result.valueOf = function () {
        return result._lastSum;
    };
    result.toString = function () {
        return result._lastSum ;
    };

    result._lastSum  = sum(arguments);

    return result;
}

`

带刺的爱情℡ 2022-05-04 13:55:59
function add() {
  return Array.from(arguments).reduce((pre, item) => pre + item, 0)
}

function curry(fn) {
  let params = [];

  function result() {
    params.push(...arguments)

    return result;
  }

  result.toString = () => { 
    const tempParams = params;
    params = [];

    return fn.call(null, ...tempParams) 
  }

  return result;
}
醉生梦死 2022-05-04 13:55:59
let timer = null
function add(...arg1){
	return function(...arg2){
		let arg = [...arg1,...arg2]
		clearTimeout(timer)
		timer = setTimeout(()=>{
			console.log(arg.reduce((p,c)=>p+c))
		},0)
		return add(...arg);
	}
}

add(2,3)(4)(5,6)(9)()(1) //30
红衣飘飘貌似仙○ 2022-05-04 13:55:59
function add(...args) { 
  add.params = add.params.concat(args)
  return add;
}
add.params = []
add.toString = function() {
  var val = add.params.reduce((a,b) => a+b)
  add.params = []
  return val;
}
function add(...args) {
  var f = function(...args1) {
    return add.apply(null, [...args, ...args1])
  }
  f.toString = () => args.reduce((a,b)=>a+b)
  return f
}
凉月流沐@ 2022-05-04 13:55:59

诸位真的是大佬---膜拜了 我看了半天算是看懂函数柯里化的应用了

function Add(a, b, c) {
  return a + b + c;
}
function cuuring(fn) {
  let finallen = fn.length;
  var args = []
  return function digui() {
    var innerargs = Array.prototype.slice.call(arguments);
    args = args.concat(innerargs);
    return args.length >= finallen ? fn.apply(null, args) : digui;
  }
}
var add1 = cuuring(Add);
console.log(add1(1)(2)(3))
野心澎湃 2022-05-04 13:55:59
let timer = null
function add(...arg1){
	return function(...arg2){
		let arg = [...arg1,...arg2]
		clearTimeout(timer)
		timer = setTimeout(()=>{
			console.log(arg.reduce((p,c)=>p+c))
		},0)
		return add(...arg);
	}
}

add(2,3)(4)(5,6)(9)()(1) //30

看来半天 不明白 toString 是怎么调用的...
看你的回答 太真实了

箜明 2022-05-04 13:55:59

感觉关键点在重写函数toString方法啊,我就一直在想,怎么又返回函数,而最后又输出结果,真棒!

草莓酥 2022-05-04 13:55:59
function add(...num) {
    let res = 0 //第一次调用函数时生成一个闭包来存储结果
    num.forEach(item => res += item) //遍历输入参数加到res上

    let ret = function (...num) {
      num.forEach(item => res += item)
      return ret
    }

    ret.toString = function () {
      return res
    }

    ret.valueOf = function () {
      return res
    }

    return ret
  }
  console.log(add(1)); // 1
  console.log(add(1)(2)); // 2
  console.log(add(1)(2)(3)); // 6
  console.log(add(1)(2)(3,7)(4,5,6));// 28 

使用了一个闭包完成了这个效果

马蹄踏│碎落叶 2022-05-04 13:55:59
function add(...num) {
    let res = 0 //第一次调用函数时生成一个闭包来存储结果
    num.forEach(item => res += item) //遍历输入参数加到res上

    let ret = function (...num) {
      num.forEach(item => res += item)
      return ret
    }

    ret.toString = function () {
      return res
    }

    ret.valueOf = function () {
      return res
    }

    return ret
  }
  console.log(add(1)); // 1
  console.log(add(1)(2)); // 2
  console.log(add(1)(2)(3)); // 6
  console.log(add(1)(2)(3,7)(4,5,6));// 28 

使用了一个闭包完成了这个效果

你这里输出的结果其实是 f 1f 6...

妄断弥空 2022-05-04 13:55:59

function add(...firstArgs) {
const result = firstArgs.reduce((pre, now) => pre + now);
const fn = (...args) => {
return add(...args, result);
};
fn.toString = () => result;
return fn;
}

学到了,fn.toString();

情话墙 2022-05-04 13:55:59
function add(...num) {
    let res = 0 //第一次调用函数时生成一个闭包来存储结果
    num.forEach(item => res += item) //遍历输入参数加到res上

    let ret = function (...num) {
      num.forEach(item => res += item)
      return ret
    }

    ret.toString = function () {
      return res
    }

    ret.valueOf = function () {
      return res
    }

    return ret
  }
  console.log(add(1)); // 1
  console.log(add(1)(2)); // 2
  console.log(add(1)(2)(3)); // 6
  console.log(add(1)(2)(3,7)(4,5,6));// 28 

使用了一个闭包完成了这个效果

你这里输出的结果其实是 f 1f 6...

在不知道会一直调用多少次的情况下, 不返回一个函数, 怎么能够继续调用呀

脱离于你 2022-05-04 13:55:59
function add(...arg) {
    let res = 0;
    function fn(...arg) {
        res += arg.reduce((total, v) => total + v, 0);
        return fn;
    }
    fn.toString = function () {
        return res
    }
    return fn(...arg)
}

console.log(add(1))
console.log(add(1)(2))
console.log(add(1)(2)(3))
console.log(add(1, 2)(3))
console.log(add(1, 2, 3))
东风软 2022-05-04 13:55:59

我觉得题目不严谨

初吻给了烟 2022-05-04 13:55:59
function add() {
  let res = [...arguments].reduce((a, b) => a + b, 0);
  const fn = function () {
    res = [...arguments].reduce((a, b) => a + b, res);
    return fn;
  };
  fn.toString = fn.valueOf = () => res;
  return fn;
}
破晓 2022-05-04 13:55:59
const add = (...rest) => {
  const args = rest

  const addFunc = (...nextRest) => {
    args.push(...nextRest)

    return addFunc
  }

  addFunc.toString = () => {
    return args.reduce((a, b) => a + b)
  }

  return addFunc
}
神爱温柔 2022-05-04 13:55:59
const add = (...args) => {
  const _add = (...args1) => {
    return add(...args, ...args1)
  }
  _add.toString = () => [...args].reduce((t, c) => t+c,  0)

  return _add
}
add(1,2)(3)(4,5)(6)
花心好男孩 2022-05-04 13:55:59

toString实在过于hacky,这题本质和各种括号加减运算差不多

枫林﹌晚霞¤ 2022-05-04 13:55:59
function add() {
    const params = [...arguments]

    recur.toString = acc;

    return recur()

    function acc() {
        return params.reduce((acc, item) => {
            acc += item;

            return acc;
        }, 0);
    }

    function recur() {
        params.push(...arguments);

        if (params.length >= 3) {
            return acc()
        } else {
            return recur
        }
    }
}

console.log("debug-", add(1, 2));
console.log("debug-", add(1));
console.log("debug-", add(1, 2)(3));
console.log("debug-", add(1)(2, 3));
console.log("debug-", add(1)(2)(3));
console.log("debug-", add(1, 2, 3));
救赎№ 2022-05-04 13:55:59
function add() {
  let args = [].slice.call(arguments);
  let fn = function(){
   let fn_args = [].slice.call(arguments)
   return add.apply(null,args.concat(fn_args))
 }
fn.toString = function(){
  return args.reduce((a,b)=>a+b)
}
return fn
}

这返回的是函数啊??

转身泪倾城 2022-05-04 13:55:59

单纯从题意触发,add调用时候必须有toString之类的触发条件;用外部变量保存每次执行累计的参数列表,执行完toString之后清空即可:

// * 柯理化函数
let concatArgs = []
function add(...args) {
  concatArgs = concatArgs.concat(args)
  return add
}
add.toString = function () {
  const res = concatArgs.reduce((pre, cur) => pre + cur, 0)
  concatArgs = []
  return res
}

console.log(add(1)(2)(3) + "") // 6
console.log(add(1)(2, 3) + "") // 6
console.log(add(1, 2)(3) + "") // 6
console.log(add(1, 2, 3) + "") // 6
console.log(add(1).toString()) // 1
console.log(add(1)(2).toString()) // 3
console.log(add(1)(2)(3).toString()) // 6
console.log(add(1)(2, 3).toString()) // 6
console.log(add(1, 2)(3).toString()) // 6
console.log(add(1, 2, 3).toString()) // 6
手心的海 2022-05-04 13:55:59

题目不严谨,有歧义。

在实际项目中如果有这样的需求,或者用 toString 这种 hack 的方式实现。

感谢同事不杀之恩吧。

const money = add(1)(2)
typeof money  // function
// 同事:“... wtf ?”


const money = add(1)(2)
if (money < 100) money(3)
// 同事:“???”


const money = add(1)(2)
console.log(money)  // f 3
// 此处省略 100+ 行代码...
console.log(money)  // money:“猜猜我变没变”

// ...卒
嗳卜坏 2022-05-04 13:55:59
function add(...args) {
    if (Number.prototype.add !== add) Number.prototype.add = add;
    return args.reduce(
        (pre, now) => pre + now,
        this instanceof Number ? this : 0
    );
}

修改Number满足吗

半窗疏影 2022-05-04 13:55:59
let timer = null
function add(...arg1){
	return function(...arg2){
		let arg = [...arg1,...arg2]
		clearTimeout(timer)
		timer = setTimeout(()=>{
			console.log(arg.reduce((p,c)=>p+c))
		},0)
		return add(...arg);
	}
}

add(2,3)(4)(5,6)(9)()(1) //30

但是这个好像不能执行add(1,2,3)这种

染柒℉ 2022-05-04 13:55:59

做一个可循环调用add函数,执行时把arg1arg2内外传入的两个参数加到一块。函数的toString方法在函数被alert或者console的时候会被调用,可以用这个方法来确定是否需要输出总结果。

function add (...arg1) {
  let t = function (...arg2) {
    return add(Array.from(arg1).concat(Array.from(arg2)).reduce((a, b)=> {return a+b}))
  }
  t.toString = ()=>{
    return Array.from(arg1).reduce((a, b)=> {return a+b})
  }
  return t
}
可是我不能没有你 2022-05-04 13:55:59
add(1); 	// 1
add(1)(2);  // 3
add(1)(2)(3); // 6
add(1)(2, 3); // 6
add(1, 2)(3); // 6
add(1, 2, 3); // 6
function add(...args) {
  let final = [...args];
  setTimeout(() => {
    console.log(final.reduce((sum, cur) => sum + cur));
  }, 0);
  const inner = function (...args) {
    final = [...final, ...args];
    return inner;
  }
  return inner;
}
流心雨 2022-05-04 13:55:59

function add() {
var a = 0;
var out = arguments;

function sum() {
    for(var i = 0; i < arguments.length; i++) {
        a += arguments[i]
    }
    return sum
}

sum.toString = function() {
    for(var i = 0; i < out.length; i++) {
        a += out[i]
    }
    return a;
}

return sum;

}

你与昨日 2022-05-04 13:55:59
const add=(a,b,c)=>a+b+c
    const currying=(fn,length)=>{
        length=length||fn.length
        return (...args)=>args.length>=length?fn(...args):currying(fn.bind(this,...args),length-args.length)

    }
    const sum=currying(add)
    console.log(sum(1)(2)(3));
    console.log(sum(1,2)(3));
    console.log(sum(1)(2,3));
    console.log(sum(1,2,3));
最美不过初阳 2022-05-04 13:55:59
function add() {
  let args = [].slice.call(arguments);
  let fn = function(){
   let fn_args = [].slice.call(arguments)
   return add.apply(null,args.concat(fn_args))
 }
fn.toString = function(){
  return args.reduce((a,b)=>a+b)
}
return fn
}
const add=(...args)=>{
        const fn=(...params)=>add(...args,...params)
        fn.toString=()=>args.reduce((a,b)=>a+b)
        return fn
    }
    console.log(add(1,2)(3).toString());
吾家有女初长成 2022-05-04 13:55:59
function add(...args) {
  let nums = [...args];

  function _add(...argsNext) {
    if (argsNext.length === 0) {
      // 不再有参数传入作为计算结果的信号
      return nums.reduce((pre, cur) => {
        return pre + cur;
      }, 0);
    } else {
      nums.push(...argsNext);
      return _add;
    }
  }

  return _add;
}
烟燃烟灭… 2022-05-04 13:55:59
function add(...a){
   let sum = (...b) => add(...[...a,...b]);  //合并参数
   let result = a.reduce((x,y) => x+y);  //对所有参数进行累加
   sum.toString = () => result;  //将结果返回
   return sum;
}
console.log(add(1,2,3)(2,2).toString());  //10
漆黑的白昼 2022-05-04 13:55:58
function add(...args) {
  let sum = 0;
  const innerAdd = (...args) => {
    args.forEach(i => (sum += i));
    return innerAdd;
  };
  innerAdd.toString = () => sum;
  return innerAdd(...args);
}
话少心凉 2022-05-04 13:55:56

还有一种方法

function add(){
	if(arguments.length === 0){
		let num = 0;
		add.args.forEach(v=>{
			num += v;
		});
		add.args = null;
		return num;
	}else{
		add.args = add.args ? add.args : [];
		add.args = add.args.concat([...arguments]);
		return add;
	}
}
add(1)(2)(3)();
add(1, 2)(3)(8)();
怂人 2022-05-04 13:55:56
function curry (fn) {
  const finalLen = fn.length
  let args = [].slice.call(this,1)
  return function currying () {
    args = args.concat(Array.from(arguments))
    const len = args.length
    return len >= fn.length ? fn.apply(this, args) : currying
  }
}
function add (a,b,c) {
  return a+b+c
}
const add1 = curry(add)
console.log(add1(1, 2)(3))
奶茶°白久 2022-05-04 13:55:35
function add(){
	let args = [...arguments];
	let addfun = function(){
		args.push(...arguments);
		return addfun;
	}
	addfun.toString = function(){
		return args.reduce((a,b)=>{
			return a + b;
		});
	}
	return addfun;
}
缱绻入梦 2022-05-04 13:55:30
function add() {
  let args = [].slice.call(arguments);
  let fn = function(){
   let fn_args = [].slice.call(arguments)
   return add.apply(null,args.concat(fn_args))
 }
fn.toString = function(){
  return args.reduce((a,b)=>a+b)
}
return fn
}
压抑⊿情绪 2022-05-04 13:55:06
const curry = (fn, arity = fn.length, ...args) =>
  arity <= args.length ? fn(...args) : curry.bind(void 0, fn, arity, ...args);
橪书 2022-05-04 13:31:33

实现 1:

function currying(fn, length) {
  length = length || fn.length; 	// 注释 1
  return function (...args) {			// 注释 2
    return args.length >= length	// 注释 3
    	? fn.apply(this, args)			// 注释 4
      : currying(fn.bind(this, ...args), length - args.length) // 注释 5
  }
}

实现 2:

const currying = fn =>
    judge = (...args) =>
        args.length >= fn.length
            ? fn(...args)
            : (...arg) => judge(...args, ...arg)

其中注释部分

  • 注释 1:第一次调用获取函数 fn 参数的长度,后续调用获取 fn 剩余参数的长度

  • 注释 2:currying 包裹之后返回一个新函数,接收参数为 ...args

  • 注释 3:新函数接收的参数长度是否大于等于 fn 剩余参数需要接收的长度

  • 注释 4:满足要求,执行 fn 函数,传入新函数的参数

  • 注释 5:不满足要求,递归 currying 函数,新的 fn 为 bind 返回的新函数(bind 绑定了 ...args 参数,未执行),新的 length 为 fn 剩余参数的长度

2022-05-04 02:36:21

之前写过 2 篇文章,可以参考一二。
1、【进阶 6-1 期】JavaScript 高阶函数浅析
2、【进阶 6-2 期】深入高阶函数应用之柯里化

其中第一篇文章给出了前三个功能的实现,并没有覆盖到后面三种。
第二篇文章实现了一个通用的柯里化函数,覆盖实现了所有功能。

~没有更多了~

关于作者

心凉

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文