一道面试题的思考

  • 白小霁
  • 8 Minutes
  • April 26, 2017

前言

这周一,参加了ali的笔试,第一道问答题目,如下图:

一种方法:

1
2
3
4
5
6
7
8
9
10
11
12
function funnyPlus(i){
var sum = 0;
function a(i){
if(arguments.length === 0){
return sum
}else{
sum += i;
return a
}
}
return a(i)
}

解题

题目中的函数调用方法,大概想到就是要用高阶函数的写法还有递归的写法。解释一下这两个名词,高阶函数在JavaScript中就是一个函数会return另一个函数;而递归形式很像,递归返回的这个函数就是自身,但是会有设置一个终止的条件。

思路

按照上面的意思大概我们要构建这样的函数

1
2
3
4
5
let sum = 0;
function funnyPlus(i){
//doing something ....
return funnyPlus
}

因为看到最后一次没有传参数,机智的看到了一个机会,所以将跳出的条件设置为参数个数为零,所以我这样写了代码:

1
2
3
4
5
6
7
8
let sum = 0;
function funnyPlus(i){
if(arguments.length === 0){
// coding
}
// coding
return funnyPlus
}

再看了整个函数的功能就是,连续的加法运算,所以添加业务代码

1
2
3
4
5
6
7
8
let sum = 0;
function funnyPlus(i){
if(arguments.length === 0){
return sum
}
sum += i
return funnyPlus
}

大概的思路就是这样,但是仍旧不能达到题目的要求,我们回顾一下题目的要求:

  1. 一个叠加的函数
  2. 每次返回计算的结果
    我们上面的,动用了全局当中的一个变量,而且每一次的调用函数计算值时,都会保留上一次计算的结果。当然你可以找到一个另一个变量来转移一下,之后在修改sum的值,就像这样(暗暗觉得有点贱气)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let sum = 0;
    function funnyPlus(i){
    if(arguments.length === 0){
    const final = sum
    sum = 0
    return final
    }
    sum += i
    return funnyPlus
    }

考虑到用了一个全局的变量,防止被其他人修改的危险,只能让函数内部产生一层闭包,来保护一个变量不会变修改,所以就有我最上面的答案:

1
2
3
4
5
6
7
8
9
10
11
12
function funnyPlus(i){
let sum = 0;
function a(i){
if(arguments.length === 0){
return sum
}else{
sum += i
return a
}
}
return a(i)
}

用一层函数的作用域来保护了sum的值,同样返回了一个新的函数,而在这个函数内部通过递归的方法在完成我们业务代码,这样就完成咯。
其实当初遇见的第一道的时候,其实蛮紧张的,因为感觉会写但是迟迟也就写出了大概的思路,哈哈,不说别的了,以上仅仅是一种写法,如果你有什么新的方法可以下方留言哦。