版本1.0 for循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var fun = (function() {
return function(a,b,n) {
if(n == 1){
return a
};
if(n == 2){
return b
}
var sum;
for (var i = 3;i <= n;i++){
sum = a + b;
a = b;
b = sum;
}
return sum
}
})();
版本2.0递归
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var fun = (function() {
return function(a,b,n) {
var sum = a + b;
n--;
if(n == 0){
return a
}
if(n == 1){
return b
}
if(n == 2){
return sum
}
return arguments.callee(b,sum,n);
}
})();
版本2.1 递归 + 惰性函数(总要练习使用嘛~)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var fun = (function() {
return function(a,b,n) {
if(n == 1){
return a
}
if(n == 2){
return b
}
fun = function (a,b,n) {
var sum = a + b;
n--;
if(n == 2){
return sum
}
return arguments.callee(b,sum,n);
}
return fun(a,b,n);
}
})();
这么写,确实能够在后续的递归循环中省去判断1,2的步骤,
但缺点是,一旦运行过n>2,那么重新调用n<2时,
会出现问题.
版本2.2 递归,惰性函数优化版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var fun = (function() {
return function(a,b,n) {
var fn = arguments.callee;//这个就是神来之笔,惰性函数弄完之后,用来改回最初版本
if(n == 1){
return a
}
if(n == 2){
return b
}
fun = function (a,b,n) {
var sum = a + b;
n--;
if(n == 2){
fun = fn;
return sum
}
return arguments.callee(b,sum,n);
}
return fun(a,b,n);
}
})();
这个写完,我自己都觉得有点看不懂,略显高级有没有
版本3.0 用私有变量缓存方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var fun = (function() {
var cache = {};
return function(a, b, n) {
cache[1] = a;
cache[2] = b;
if(cache[n]) {
return cache[n]
} else {
cache[n] = fun(a,b,n-1) + fun(a,b,n-2);
}
return cache[n];
}
})();
这样也能节省性能,
缺点是会占用缓存,用空间换区速度
写完这个发现,版本2.0的递归写得很丑.
版本4.0 标准递归?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var fun = (function() {
return function(a, b, n) {
if(n == 1) {
return a
}
if(n == 2) {
return b
}
return fun(a, b, n - 1) + fun(a, b, n - 2)
}
})();
这才是标准递归:关系非常的明确,版本2.0的递归还是受到for循环的思维影响.
不过版本2.0的启示是:
是否所有for循环都可以用递归来代替?
不过教程里说递归方式有个缺点:性能会低一点,因为函数会层层嵌套,调用多次函数.