美文网首页
JS 递归函数

JS 递归函数

作者: 抽疯的稻草绳 | 来源:发表于2020-12-26 14:39 被阅读0次

什么是递归函数?

一个通过函数名调用自身的函数

递归函数的注意点

  • 一定要有结束条件,否则会导致死循环
  • 能用递归函数实现的需求,就一定可以用循环调用函数来解决,只是代码简洁与性能不同而已

递归函数的应用场景

1.求阶乘: 求n的阶乘
  • 循环写法
        function getMul(n){
            var data = 1;
            for(var i = 1;i<=n;i++){
                data *= i
            }
            return data;
        }
        console.log(getMul(4));//24

  • 递归写法
    a.推理版:中间省略
        function getMul(n){
            if(n == 1){
                return 1;
            }else if(n == 2){
                return 2 * getMul(1);
            }else if(n == 3){
                return 3 * getMul(2)
            }
            //*****
            else if(n == n){
                return n * getMul(n-1);
            };
        };
        console.log(getMul(4));//24

b.精简版:三元表达式

        function getMul(n){
            return n == 1 ? 1 : n * getMul(n-1);
        };
        console.log(getMul(4));//24

2.求1-n的累加和
  • 循环写法
        function getSum(n){
            var data = 0;
            for(var i = 1;i<=n;i++){
                data += i;
            }
            return  data;
        };
        console.log(getSum(4));//10

  • 递归写法
    a.推理版:中间省略
        function getSum(n){
            if(n == 1){
                return 1;
            }else if(n == 2){
                return n + getSum(1);
            }else if(n == 3){
                return n + getSum(2);
            }else if(n == 4){
                return n + getSum(3);
            }
           // ………………
            else if(n == n){
                return n + getSum(n-1)
            }
        };
        console.log(getSum(4));//10

b.精简版:三元表达式

        function getSum(n){
            return n==1 ? 1:n + getSum(n-1);
        };
        console.log(getSum(4));//10

3.求斐波拉契数列
  • 斐波拉契数列: 前面两个数字是固定的1,从第三个数字开始,每一个数字都是前面两个数字的和
循环数组写法(性能好)

思路:1.每次计算都是前两个数字之和,其他的数据没有什么用,所以每次只计算两个
arr[n]=arr[n-1]+arr[n-2]

image
        function getData(n) {
            var arr = [1, 1];
            for (var i = 2; i < n; i++) {
                arr[i] = arr[i - 1] + arr[i - 2];
            };
            console.log(arr);//[1,1,2,3,5,8,13,21,34,55]
            return arr[arr.length - 1];
        };
        console.log(getData(10)); //10

递归写法

a.推理版:中间省略


        function getData(n) {
            if(n == 1 || n == 2){
                return 1;
            }else if(n == 3){
                return getData(2) + getData(1);
            }else if(n == 4){
                return getData(3)+getData(2);
            }else if(n == 5){
                return getData(4) + getData(3)
            }
           // …………
            else if(n == n){
                return getData(n-1) + getData(n-2)
            };
        };
        console.log(getData(10)); //10

b.精简版:三元表达式

        function getData(n) {
            return (n == 1 || n == 2)?1 : getData(n-1) + getData(n-2);
        };
        console.log(getData(10)); //10

4.遍历DOM树:获取所有的后代元素

a.需求:获得div中所有的后代元素
b.思路:获取father的子代元素。 继续检查该元素是否有子代元素,
如果有则继续循环获取子代,依次类推,形成递归调用

            <div id="father">
        <div>
            <span>1</span>>
        </div>
        <p>
            <span>11</span>
            <span>22</span>
        </p>
        <a href="#">boJack</a>
        <div>
            <div>
                <b>Todd</b>
            </div>
        </div>
    </div>
    <script>
        var father = document.getElementById('father');
        var list = []; //声明空数组存储所有的后代元素
        function getHouDai(ele) {
            for (var i = 0; i < ele.children.length; i++) {
                list.push(ele.children[i]);
                getHouDai(ele.children[i]);
            };
        };
        getHouDai(father);
        console.log(list);//[span,p,span,span,a,div,div,b]

// 遍历整颗DOM树
        getHouDai(document);
        console.log(list);
    </script>

经典面试题以及推荐用法

a.写出该题打印的值

        var res = (function(n){ return n==1?1:n*arguments.callee(n-1)})(6);
        console.log('res' + res);//res720

考察的知识点:argument.callee

  • argument.callee是一个指向正在执行的函数的指针,使用它来代替函数名,可以确保无论怎样调用函数都不会出问题
        function res(n) {
            return n ==1 ? 1 : n * res(n - 1);
        };
        var  data = res;
        res = null;
        console.log(data(4));
        //res is not a function

由于res变量设置为Null,结果指向原始函数的引用只剩下一个,res已经不是函数,而调用data()会执行res,所以会报错;而使用arguments.callee可以解决这个问题

        function res(n) {
            return n ==1 ? 1 : n * arguments.callee(n - 1);
        };
        var  data = res;
        res = null;
        console.log(data(4));//24

推荐用法

  • 严格模式:使用arguments.callee会报错,不过我们可以通过命名函数表达式来达到相同的效果
    以下代码创建了一个f()的命名函数表达式,赋值给res变量,即使把函数赋值给另一个变量,函数的名字依然有效,递归能正常完成,这种方式在严格模式和非严格模式都能运行
        var res=(function f(n) {
            return n ==1 ? 1 : n * f(n - 1);
        });
        console.log(res(4));//24

相关文章

  • JS递归函数

    什么是递归函数? 递归函数是在一个函数通过名字调用自身的情况下构成的。像这样: “从前有座山,山里有座庙,庙里有个...

  • JS 递归函数

    什么是递归函数? 一个通过函数名调用自身的函数 递归函数的注意点 一定要有结束条件,否则会导致死循环 能用递归函数...

  • JavaScript 之递归问题的解决

    递归: 递归函数在定义的时候需要调用自己,因此会用到自己的函数名;但是在js中会出现如下的问题: function...

  • JS 高级(函数、作用域、闭包、this、垃圾回收)

    JS 函数 函数分为两类具名函数、匿名函数,其变型可以包括自执行函数、递归函数 具名函数含有名字的函数functi...

  • 2018-03-21 JS重构指标

    递归函数不要使用函数名,改用命名函数表达式相关资料 : 原因 JS创建函数的三种方式

  • Day10递归函数、模块、迭代器、生成器

    一、递归函数 1、什么是递归函数 在函数中调用函数本身的函数就是递归函数。 2、递归的作用 循环能做的递归都能做 ...

  • day11 函数(3)

    递归函数 实际开发的时候,能不用递归就不用 什么是递归函数 函数中调用函数本身的函数就是递归函数 递归的作用: 循...

  • python 递归函数

    递归函数 递归函数 : 在函数的调用自身 递归边界 : 退出递归的终止条件 例1,函数func如果没有设备递归边界...

  • day11-日常(递归函数、模块、迭代器、生成器)

    递归函数(实际开发的时候,能不用递归就不用) 1.什么是递归函数 函数中调用函数本身的函数就是递归函数 2.递归的...

  • 2019-01-07day11学习总结

    递归函数 实际开发的时候能不用递归就不用递归 1. 什么是递归函数 函数中调用函数本身的函数就是递归函数 2. 递...

网友评论

      本文标题:JS 递归函数

      本文链接:https://www.haomeiwen.com/subject/ktxsnktx.html