先看一个问题
有一个函数 multiply
可以无限调用,如:multiply(1,2)(4)(1,2)(),求所有数的合。
分析:涉及到的点:
柯里化
,callee
CODE
var multiply = (function () {
let sum = 0;
return function() {
var arr = [].slice.call(arguments);
if(arr.length <=0) {
return sum;
}else {
arr.forEach(item => sum+=item)
}
return arguments.callee; //callee:正被执行的Function对象。
}
})();
var test = multiply(1,2)(4)(1,2)();
console.log(test);
思路解析
- 首先一个函数可以无限次调用,需要
return
一个function
。这个函数需要做的操作是计算和并且当无入参时返回结果。此时就需要通过返回函数本身来实现无限调用,返回函数本身可以通过return arguments.callee
或者return 函数名
这两种方法。 - 入参不限并且统一处理就涉及到的是一个柯理化的概念。
柯里化: 是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。其实,柯里化就是用闭包原理实现函数参数的合并,然后再运行函数。
[].slice.call(arguments)
把伪数组转化返回一个正常的Array. 然后通过闭包实现sum的累加。
链式函数
对于上面的问题如果没有最后的(),该怎么写呢。
var multiply = function () {
var sum = 0;
var _args = [].slice.call(arguments);
_args.forEach(item => {
sum += item;
});
function s() {
var args = [].slice.call(arguments);
args.forEach(item => {
sum += item;
});
return s
}
s.toString = function() {
return sum + '';
}
s.valueof = function () {
return sum;
}
return s;
};
var test = multiply(1, 2)(4)(1, 2);
console.log(test1);
解释: multiply函数内部返回一个s函数,修改了期toString和valueof方法,目的是为了在进行类型转化时返回值。