博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
递归函数的执行
阅读量:5968 次
发布时间:2019-06-19

本文共 1124 字,大约阅读时间需要 3 分钟。

递归(Recursion)

一个函数可以指向并调用自身(call itself)。有三种方法可以达到这个目的:

  1. 函数名

  2. arguments.callee

  3. 作用域下的一个指向该函数的变量名

上述概念引用自,对递归概念不清楚的可以自行查看;

递归函数的执行

在这里我们讨论一下递归函数中递归后的语句如何执行,先看这样一个例子:

function rec(x){if(x!==1){   console.log(x)   rec(x-1)   console.log(x)    }   }rec(5) //输出为5 4 3 2 2 3 4 5

以上这段代码执行的结果就是递归前的语句顺序执行,递归后的语句倒序执行。初看到这段代码,完全不能理解它执行的顺序。通过调试让代码逐行执行,可以看到执行的顺序,其实就是一层一层执行递归,每执行到rec(x-1)时就重新执行该函数,递归后的语句会在递归执行到最里层后再由内向外输出。

很好的总结了递归的特性如下:
1 每一次函数调用都会有一次返回.当程序流执行到某一级递归的结尾处时,它会转移到前一级递归紧接着的后面继续执行.
2 递归函数中,位于递归调用前的语句和各级被调函数具有相同的顺序.如打印语句 #1 位于递归调用语句前,它按照递归调用的顺序被执行了 4 次.
3 每一级的函数调用都有自己的私有变量.
4 递归函数中,位于递归调用语句后的语句的执行顺序和各个被调用函数的顺序相反.
5 虽然每一级递归有自己的变量,但是函数代码并不会得到复制.
6 递归函数中必须包含可以终止递归调用的语句.

在这个例子中,终止递归调用的条件是if(x!==1),如果调用时取值x小于1,会构成死循环;这个例子中的递归采用了通过函数名调用的方法。

下面我们再讨论一下argumengts.callee方式,在ES5严格模式下,callee是无法使用的,原因详见。

这是callee的一个独特的用法,在这个结构下无法替代,

function factorial(num){    if (num <= 1){        return 1;    } else {        return num * factorial(num-1);    }}var anotherFactorial = factorial;alert(anotherFactorial(4)); //出错!

但我们可以用下面这种方式,把递归函数赋值给一个变量:

var factorial = (function f(num){if (num <= 1){return 1;} else {return num * f(num-1);}});

转载地址:http://jvqax.baihongyu.com/

你可能感兴趣的文章
二十四种设计模式:策略模式(Strategy Pattern)
查看>>
统计某个字符串中指定字符串出现的次数
查看>>
asp.net三层结构中,SQL助手类DbHelperSQL
查看>>
scala map和flatMap
查看>>
.Net Core下使用 RSA
查看>>
python 数据库中文乱码 Excel
查看>>
利用console控制台调试php代码
查看>>
递归算法,如何把list中父子类对象递归成树
查看>>
jsf初学解决GlassFish Server 无法启动
查看>>
【Gson】2.2.4 StackOverflowError 异常
查看>>
hdu 1050 (preinitilization or postcleansing, std::fill) ...
查看>>
Form各键盘触发子所对应的“按键”
查看>>
【java IO】使用Java输入输出流 读取txt文件内数据,进行拼接后写入到另一个文件中...
查看>>
Linux系统下安装rz/sz命令及使用说明
查看>>
点击按钮抓不到页面的参数
查看>>
CentOS 6.5 下安装 Redis 2.8.7
查看>>
第一次模拟面试
查看>>
window.showModalDialog
查看>>
Pycharm选择pyenv安装的Python版本
查看>>
?Sized 和 Sized
查看>>