第 84 题:请实现一个 add 函数,满足以下功能
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
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
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(57)
为什么console的时候不会自动调用 toString方法呢,上面的答案在我的chrome控制台里返回的都是函数
可以实现连续不定参数的调用,返回参数和
我也遇到了类似的问题,toString的方案在新版的Chrome(我的版本是98)似乎不起作用,打印出来的是一个函数,需要显式调用才能返回结果
建议把题目描述清楚
如果要做成高阶函数以便支持任意迭代器,累加器的初始值设定要麻烦一点
尤其是考虑到任意长度输入和空输入,要多一些判断逻辑。
写了一个支持以上所有特性的
@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)
`
`
诸位真的是大佬---膜拜了 我看了半天算是看懂函数柯里化的应用了
看来半天 不明白 toString 是怎么调用的...
看你的回答 太真实了
感觉关键点在重写函数toString方法啊,我就一直在想,怎么又返回函数,而最后又输出结果,真棒!
使用了一个闭包完成了这个效果
你这里输出的结果其实是
f 1
、f 6
...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();
在不知道会一直调用多少次的情况下, 不返回一个函数, 怎么能够继续调用呀
我觉得题目不严谨
https://theanubhav.com/2019/02/03/js-currying-in-interview/#first-implement-add23-in-javascript
toString实在过于hacky,这题本质和各种括号加减运算差不多
这返回的是函数啊??
单纯从题意触发,add调用时候必须有toString之类的触发条件;用外部变量保存每次执行累计的参数列表,执行完toString之后清空即可:
题目不严谨,有歧义。
在实际项目中如果有这样的需求,或者用 toString 这种 hack 的方式实现。
感谢同事不杀之恩吧。
修改Number满足吗
但是这个好像不能执行add(1,2,3)这种
做一个可循环调用
add
函数,执行时把arg1
和arg2
内外传入的两个参数加到一块。函数的toString
方法在函数被alert
或者console
的时候会被调用,可以用这个方法来确定是否需要输出总结果。function add() {
var a = 0;
var out = arguments;
}
还有一种方法
实现 1:
实现 2:
其中注释部分
注释 1:第一次调用获取函数 fn 参数的长度,后续调用获取 fn 剩余参数的长度
注释 2:currying 包裹之后返回一个新函数,接收参数为 ...args
注释 3:新函数接收的参数长度是否大于等于 fn 剩余参数需要接收的长度
注释 4:满足要求,执行 fn 函数,传入新函数的参数
注释 5:不满足要求,递归 currying 函数,新的 fn 为 bind 返回的新函数(bind 绑定了 ...args 参数,未执行),新的 length 为 fn 剩余参数的长度
之前写过 2 篇文章,可以参考一二。
1、【进阶 6-1 期】JavaScript 高阶函数浅析
2、【进阶 6-2 期】深入高阶函数应用之柯里化
其中第一篇文章给出了前三个功能的实现,并没有覆盖到后面三种。
第二篇文章实现了一个通用的柯里化函数,覆盖实现了所有功能。