- 什么是递归?
- 一种特殊的嵌套调用
- 函数自己调用自己或者调用其他函数后再次调用自己
- 只要是函数之间产生循环一定是递归调用
- 以斐波拉契数列为例
斐波拉契数列:1,1,2,3,5,8,13,21,34…
斐波拉契数列函数:
非递归:
function fibonacci(n) {
let a = 1,
b = 1,
temp = 0;
if(n<2) {
return 1;
}
for (var i = 3; i <= n+1; i++) {
temp = a + b;
a = b;
b = temp;
}
return temp;
}
递归
function fibonacci(n) {
if (n < 2) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
可以看出,递归版的求斐波拉契函数比非递归版代码少一些,所以我们可以使用递归来减少代码量。
可是,如果函数名称的名称改变的话,递归是否能正常使用呢?
function modiF(n) {
if (n < 2) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
答案当然是不能啦!
如果修改了函数名称,内部名称没有修改,那么浏览器就会显示我们内部的函数没有定义,则会报下面错误。
那么如何解决这种问题呢?
在JS中有两种方法可以解决,我们一起来看看:
- 使用arguments.callee()函数
arguments.callee是一个指向正在执行函数的指针,因此我们可以使用它来解决修改函数名称的问题。
function fibonacci(n) {
if (n < 2) {
return 1;
}
return arguments.callee(n - 1) + arguments.callee(n - 2);
}
console.log(fibonacci(5));
来看看运行结果
浏览器并没有报出任何错误,由此可见,arguments.callee()函数可以用于递归。
值得注意的是,在严格模式下访问arguments.callee()会导致错误。
看看下面例子:
"use strict" //开启了严格模式哦
function fibonacci(n) {
if (n < 2) {
return 1;
}
return arguments.callee(n - 1) + arguments.callee(n - 2);
}
console.log(fibonacci(5));
浏览器会报以下错误:
所以,使用arguments.callee()方法时,应该注意是否为严格模式。
- 使用命名函数表达式来达成递归
var fibonacci = (function f(n) {
if (n < 2) {
return 1;
}
return f(n - 1) + f(n - 2);
})
console.log(fibonacci(5));
来看看执行结果把!
毫无疑问,命名函数表达式可以正常执行fibonacci()函数,值得说一下,命名函数表达式不受严格模式的限制,可以自有使用。
命名函数表达式是什么?
命名函数就是给一个变量赋值一个函数,并给函数起一个别名。
例子:
var a = function b() {
console.log("我是命名函数表达式");
}
a();
文章到此结束,我是一个喜欢前端技术的小菜鸟,各位,再见~~~