题:写一个关于按照下面方式调用都能正常工作的sum方法,如果可以,写出sum方法的扩展形式。
面试题示例调用代码:
console.log(sum(2,3));//output 5
console.log(sum(2)(3));//output 5
这个我拿到手之后,第一个很好实现,难的是第二个,看到第二个的时候我心里想的是这个方法最后要return一个函数,而且是一个能参数累加的函数,这又让我想起jquery的链式调用,也有点类似调用promise的感觉,因为每次调用promise都会返回一个promise对象,这也是我想到链式调用的导火线。但,怎么实现呢?
首先第一个:
function sum(x,y){
return x + y;
}
了解过js的人都知道会这么写,那么看第二个具体怎么实现呢?首先我们要知道函数是有显式参数和隐式参数之分的,显式参数如第一个实现里的x和y,而隐式参数也就是函数的内置对象arguments,arguments对象包含了函数调用的参数数组。
第二个(包括将第一个实现):
var sum = function (){
var cache;
if (arguments.length === 1) {
cache = arguments[0];//如果arguments对象的长度为1,也就是参数只有1个时,将这个参数赋值给cache,暂存
return function (number){//返回一个函数,函数里的参数(也就是第二个括号里的参数)与之前第一个括号里的参数相加
return cache + number
}
}else{
return arguments[0] + arguments[1]//如果arguments对象的长度不为1,那么两个参数相加
}
}
console.log(sum(2,3));//5
console.log(sum(2)(3));//5
这个实现主要要注意,sum(2)(3)的运算顺序实际上是先运算sum(2)然后再运算sum(3),实现方法是先将第一个括号里的参数2暂存,然后将2与第二个括号里的3相加并返回。
扩展:
如果我要这样实现:
console.log(sum(2,3,4,5,6,...,n));
console.log(sum(2)(3)(4)(5)(6)...(n));
那么该怎么实现呢?上面的方法不再适用了,因为arguments对象的长度不固定,是动态变化的。而我们要实现上述参数的两种形式,且实现参数累加的效果,所以我们可以分为两种情况分别实现。
function sum(...args){//这里的三个点...是扩展运算符,该运算符将一个数组,变为参数序列。
if([...args].length==1){//判断参数个数的形式是否为1个,即第二种形式
var cache = [...args][0];//将第一个参数的值暂存在cache中
var add = function (y){//创建一个方法用于实现第二个条件,最后并返回这个方法
cache += y;
console.log(cache)
return add;
}
return add;
}
else{//这里就是参数的第一种形式
var res = 0;//这里最好先声明要输出的变量,并给其赋值,不然值定义而不赋值会输出NaN,因为js将undefined+number两个数据类型相加结果为NaN
for(var i = 0;i<[...args].length;i++){
res += [...args][i]; //参数累加
}
console.log(res)//输出最后的累加结果
}
}
sum(2,3,4);//9
sum(2)(3)(4)(5);//5//9//14
扫盲:
1.函数括号中的...args的三个点表示扩展运算符,该运算符将一个数组变为参数序列,例如:
function sum(1,2,...[3,4,5],6,7){} == function sum(1,2,3,4,5,6,7){}
2.js会将undefined+number两种数据类型相加处理结果为NaN。