JavaScript递归详解:从基础概念到实战应用
本文深入解析JavaScript中的递归函数,阐述其定义、工作原理及防止栈溢出的关键退出条件。通过阶乘、斐波那契数列及嵌套对象查找三个具体案例,详细演示递归代码的编写方法与执行逻辑,帮助开发者掌握递归在解决复杂数据结构问题中的实际应用。
一、递归的基本概念
递归函数是指函数在内部调用自身的机制。简单来说,当函数执行过程中再次调用自身时,即构成递归。
具体实现方式如下:
function fn(){
fn();
}
fn();
上述代码定义了一个递归函数。若直接执行打印操作,会出现错误。原因在于:

递归的行为类似于循环。若未设置返回值或退出条件,函数将无限执行,导致死循环。因此,我们必须明确:
鉴于递归极易引发“栈溢出”错误(stack overflow),必须设置明确的退出条件 return 以终止调用。
正确的递归写法应包含终止逻辑。以打印五次“你好”为例,代码结构如下:
var num = 1;
function fn(){
console.log('你好');
if(num == 5){
return;
}
num++;
fn();
}
fn();
执行上述代码后,输出结果为:

理解递归定义后,接下来探讨如何利用递归解决具体问题。
二、递归在数学计算中的应用
1、求1 * 2 * 3 * 4 …*n的阶乘
相关实现代码如下:
function fn(n){
if(n == 1){
return 1;
}
return n*fn(n-1);
}
console.log('1-20的阶乘为:'+fn(20));
console.log('1-10的阶乘为:'+fn(10));
console.log('1-5的阶乘为:'+fn(5));
代码执行后的打印结果为:

2. 计算斐波那契数列
斐波那契数列(又称“兔子数列”)是一个特定序列:、1、1、2、3、5、8、13、21、34、……,,其中从第三项开始,每一项的值等于前两项之和。通过输入参数n,可获取对应位置的数值。
具体代码实现如下:
function fb(n){
if(n === 1 || n === 2){
return 1;
}
return fb(n-1) + fb(n-2);
}
console.log('第3项斐波那契数列值为:'+fb(3));
console.log('第10项斐波那契数列值为:'+fb(10));
运行上述代码,打印结果为:

三、利用递归处理嵌套数据对象
根据id字段查找并返回对应的数据对象
现有如下数据结构示例:
var date = [{
id:1,
name:'电器',
goods:[{
id: 11,
gname:'手机'
},{
id: 12,
gname: '电脑'
}]
},{
id:2,
name:'服饰',
goods:[{
id : 21,
gname:'裤子'
},{
id : 22,
gname : '外套'
}]
},{
id : 3,
name: '食品'
}];
现需通过输入id参数,返回匹配的数据对象。
首先,可利用for...Each()遍历数组获取每一项的值,示例如下:
function getId(array,id){
array.forEach(function(value){
console.log(value);
})
}
getId(date,1);
该操作的打印结果为:

若需获取id为1的对象值,可按以下方式操作:
function getId(array,id){
array.forEach(function(value){
if(value.id === id){
console.log(value);
}
})
}
getId(date,1);
此时打印结果为:

上述方法可行,但若需获取id为11的对象值呢?直接调用原函数无法实现,因为for...Each()仅遍历了外层对象,未深入内层分类。此时,需通过递归调用getId(array,id)函数来深入获取内层对象值。
具体操作代码如下:
function getId(array,id){
array.forEach(function(value){
if(value.id === id){
console.log(value);
}else if(value.goods && value.goods.length !=0){
getId(value.goods,id);
}
})
}
// getId(date,1);
getId(date,11);
执行上述代码,打印结果为:

至此,关于JavaScript递归的详细解析已完成。如需了解更多JavaScript递归相关内容,请查阅本站过往文章或继续阅读后续相关文章,感谢大家的支持!
ES6模块化中js文件怎么用import和export交互
2026-11-05 17:00:48
JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53
