之前参加过一次笔试
里面有道题目就是编写一个add函数
add(2)(3)(4) //输出9
然后再考虑他的拓展性
当时我就懵逼了
网上也查过相关的解答 但还是看不懂....
这是网上的一个解答
function add(x) {
var sum = x;
var tmp = function (y) {
sum = sum + y;
return tmp;
};
tmp.toString = function () {
return sum;
};
return tmp;
}
console.log(add(1)(2)(3)); //6
console.log(add(1)(2)(3)(4)); //10
疑惑的是这部分
var tmp = function (y) {
sum = sum + y;
return tmp;
};
tmp.toString = function () {
return sum;
};
return tmp;
求好心人解答
以下回答假设您已经了解闭包的的相关知识
可以解析为
add(2)返回函数A
A(3)返回函数B
B(4)返回函数C
那么初步的做法是
add函数执行后返回一个函数对象,这个函数对象执行后再返回一个新函数,这样一直执行下去
代码这样实现后,执行
输出的result为9,符合题目的要求
然后再考虑他的拓展性
上面的代码符合我只调用3次函数的情况,
如果要求计算
上面的实现代码就歇菜了~~~
子所以出现问题是上面的实现最后返回一个变量值,而不是一个函数对象。
好吧,那么我们按前面的写法,继续返回函数,
接下来的问题是如果要调用的次数是未知的(实际上也是未知的),继续按上面代码的写法,是一个不可能完成的任务
但是我们可以发现返回的每一个函数执行的逻辑都是一样的,就此我们可以精简下代码,让函数返回后返回自身,哈哈这就是链式调用的写法,
嗯嗯add(2)(3)(4)就是一个链式调用
但是
并没有输出我们预料的结果14而是一个函数的字符串表示,想想也不奇怪,你每次函数调用后返回的一个函数对象,那么console.log输出就是一个函数对象的字符串表示了。
那么怎么能把结果输出呢?
2种方法
第1种方法,在函数中添加判断,当没有输入参数时,直接返回调用的结果而不是返回函数
调用时和前面的有点区别
第2中方法利用JS中对象到原始值的转换规则
我们就为函数对象添加一个valueOf方法和toString方法
个人认为这样的写法很不好~函数调用语义不清晰
PS:还可以这样实现