一文深入详解js中的递归

 更新时间:2025年12月19日 09:48:24   作者:小明记账簿  
递归函数是一种在函数体内部直接或间接调用自身的函数,在JavaScript中递归函数可以用来解决可以分解为相似子问题的问题,这篇文章主要介绍了js中递归的相关资料,需要的朋友可以参考下

1. 什么是递归

在 JavaScript 中,递归是指一个函数在其定义中直接或间接地调用自身的编程技巧。递归函数通常包含两个部分:

  • 基本情况(Base Case):也称为终止条件,是递归函数停止调用自身的条件。如果没有基本情况,递归函数将无限循环调用,最终导致栈溢出错误。
  • 递归情况(Recursive Case):函数调用自身的部分,通过不断地缩小问题的规模,逐步接近基本情况。

2. 递归的优缺点

优点

  • 代码简洁:递归可以用较少的代码解决一些复杂的问题,尤其是那些具有递归结构的问题,如树的遍历、阶乘计算等。
  • 逻辑清晰:递归能够更自然地表达问题的本质,使代码的逻辑更加清晰易懂。

缺点

  • 性能问题:递归调用会消耗大量的栈空间,因为每次调用函数都会在调用栈中创建一个新的栈帧。如果递归深度过大,可能会导致栈溢出错误。
  • 效率较低:递归调用会有额外的函数调用开销,包括参数传递、栈帧的创建和销毁等,因此在性能上可能不如迭代方法。

3. 如何实现递归

实现递归函数需要遵循以下步骤:

  • 定义基本情况,确保递归能够终止。
  • 定义递归情况,通过调用自身来解决规模更小的子问题。

以下是一个计算阶乘的递归函数示例:

function factorial(n) {
    // 基本情况:当 n 为 0 或 1 时,阶乘为 1
    if (n === 0 || n === 1) {
        return 1;
    }
    // 递归情况:n 的阶乘等于 n 乘以 (n-1) 的阶乘
    return n * factorial(n - 1);
}

// 调用递归函数
const result = factorial(5);
console.log(result); // 输出 120

4. 什么情况下使用递归

递归适用于以下情况:

  • 问题具有递归结构:如树、图等数据结构的遍历,递归能够更自然地处理这些结构。
  • 问题可以分解为规模更小的子问题:通过不断地将问题分解为更小的子问题,最终达到基本情况。

5. 更多递归示例

斐波那契数列

斐波那契数列是指这样一个数列:0、1、1、2、3、5、8、13、21、34、…… ,在数学上,斐波那契数列以如下递推的方法定义:F(0)=0F(0)=0F(0)=0F(1)=1F(1)=1F(1)=1, F(n)=F(n−1)+F(n−2)F(n)=F(n - 1)+F(n - 2)F(n)=F(n1)+F(n2)n≥2n ≥ 2n2n∈N∗n ∈ N*nN)。

function fibonacci(n) {
    // 基本情况:当 n 为 0 或 1 时,直接返回 n
    if (n === 0 || n === 1) {
        return n;
    }
    // 递归情况:第 n 个斐波那契数等于第 (n-1) 个和第 (n-2) 个斐波那契数之和
    return fibonacci(n - 1) + fibonacci(n - 2);
}

// 调用递归函数
const fibResult = fibonacci(6);
console.log(fibResult); // 输出 8

遍历 DOM 树

递归可以用于遍历 DOM 树,访问每个节点。

<!DOCTYPE html>
<html lang="en">

<body>
    <div id="parent">
        <div>Child 1</div>
        <div>Child 2</div>
    </div>
    <script>
        function traverseDOM(node) {
            // 处理当前节点
            console.log(node.nodeName);
            // 递归遍历子节点,这里的子节点必须是两个及两个以上
            for (let i = 0; i < node.childNodes.length; i++) {
                const child = node.childNodes[i];
                if (child.nodeType === 1) { // 只处理元素节点
                    traverseDOM(child);
                }
            }
        }

        // 获取根节点
        const root = document.getElementById('parent');
        // 调用递归函数
        traverseDOM(root);
    </script>
</body>

</html>

在上述示例中,traverseDOM 函数递归地遍历 DOM 树,访问每个元素节点并打印其节点名称。

总结

到此这篇关于js中递归的文章就介绍到这了,更多相关js中递归内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • js中递归函数的使用介绍

    js中递归函数的使用介绍

    所谓的递归函数就是在函数体内调用本函数。使用递归函数一定要注意,处理不当就会进入死循环。递归函数只有在特定的情况下使用 ,比如阶乘问题
    2012-10-10
  • Javascript中async与await的捕捉错误详解

    Javascript中async与await的捕捉错误详解

    这篇文章主要为大家详细介绍了Javascript中async与await的捕捉错误,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 微信小程序-详解数据缓存

    微信小程序-详解数据缓存

    每个微信小程序都可以有自己的本地缓存,本篇文章主要介绍了微信小程序-详解数据缓存,可以通过函数可以对本地缓存进行设置、获取和清理,有兴趣的可以了解一下。
    2016-11-11
  • 原生js实现改变随意改变div属性style的名称和值的结果

    原生js实现改变随意改变div属性style的名称和值的结果

    在本文将为大家介绍下如何用原生js和jQuery实现随意改变div属性,和重置,具体实现如下,感兴趣的朋友可以参考下,希望对大家有所帮助
    2013-09-09
  • 如何使用less实现随机下雪动画详解

    如何使用less实现随机下雪动画详解

    这篇文章主要给大家介绍了关于如何使用less实现随机下雪动画的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • BootStrap表单控件之文本域textarea

    BootStrap表单控件之文本域textarea

    这篇文章主要介绍了BootStrap表单控件之文本域textarea,需要的朋友可以参考下
    2017-05-05
  • JavaScript XML实现两级级联下拉列表

    JavaScript XML实现两级级联下拉列表

    用xml作为存储容器,不用数据库,速度和效率高些。
    2008-11-11
  • javascript 通用滑动门tab类

    javascript 通用滑动门tab类

    滑动门JS并封装成类
    2008-03-03
  • 原生js+canvas实现验证码

    原生js+canvas实现验证码

    这篇文章主要为大家详细介绍了原生js+canvas实现验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • Java File类的常用方法总结

    Java File类的常用方法总结

    这篇文章主要介绍了Java File类的常用方法总结,本文讲解了File类的常用方法,并对一些方法给出了代码示例,需要的朋友可以参考下
    2015-03-03

最新评论