博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个JavaScript递归引出的问题
阅读量:7158 次
发布时间:2019-06-29

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

递归引出问题

 最近在看一本JS方面的书,名字叫《JavaScript语言精粹(修订版)》。在看到递归这一节的时候,有一段代码让我想了大概几分钟才想明白是怎么回事,代码如下:

var haoni = function(disc, src, aux, dst){            if(disc > 0){                haoni(disc - 1, src, dst, aux);                document.writeln('Move disc ' + disc + ' from ' + src + ' to ' + dst + '
'); haoni(disc -1, aux, src, dst); } }; haoni(3, 'Src', 'Aux', 'Dst');
View Code

这是一个有关“汉诺塔”的js实现代码。我主要是看过输出的结果有点不明白。输出如下:

Move disc 1 from Src to DstMove disc 2 from Src to AuxMove disc 1 from Dst to AuxMove disc 3 from Src to DstMove disc 1 from Aux to SrcMove disc 2 from Aux to DstMove disc 1 from Src to Dst

或许这样的输出还看不出什么。如果你在每句代码下添加一句打印的代码,结果就很让人迷糊了,如:

var haoni = function(disc, src, aux, dst){            document.write('111
'); if(disc > 0){ document.write('222
'); haoni(disc - 1, src, dst, aux); document.write('333
'); document.writeln('Move disc ' + disc + ' from ' + src + ' to ' + dst + '
'); document.write('444
'); haoni(disc -1, aux, src, dst); document.write('555
'); } document.write('666
'); }; haoni(3, 'Src', 'Aux', 'Dst');
View Code

结果如下:

111222111222111222111666333Move disc 1 from Src to Dst444111666555666333Move disc 2 from Src to Aux444111222111666333Move disc 1 from Dst to Aux444111666555666555666333Move disc 3 from Src to Dst444111222111222111666333Move disc 1 from Aux to Src444111666555666333Move disc 2 from Aux to Dst444111222111666333Move disc 1 from Src to Dst444111666555666555666555666
View Code

如果你仔细看下打印的结果,你会发现结果很有意思,这里可以自己发现哦-_-!。

 

思考问题-查找资料

 细心的人应该会看出上面的疑问。为什么会这样:

666333   //为什么666之后会是333Move disc 1 from Src to Dst

这里就要说点其他的了。

JavaScript中有一个重要的东西叫“执行环境”。执行环境定义了变量或者函数有权访问的其他数据,决定了他们各自的行为。而每个执行环境都有一个和他有关的变量对象,环境中定义的所有变量和函数都保存在这个对象中。每个函数都有自己的执行环境。当执行流进入一个函数的时候。函数的执行环境会被推入一个环境栈中。而函数执行之后栈会将他的执行环境弹出,把控制权返回给之前的执行环境。

这段话摘自:《JavaScript高级程序设计》。所以上面的问题就有了解答。

 

从一个例子解答问题

我们先来看一个小例子:

(function(num){            if(num > 1){                console.log('11');                arguments.callee(num-1);                console.log('22');            }        }(3));

 

结果:

11112222

 

根据上面资料的介绍,这个结果也就很好理解了。当第一次执行的时候num是3,进入if判断打印‘11’。然后调用自身,这个时候函数(这里叫A)会进入另外一个函数(这里叫B)而新的执行环境也会进来(虽然另外一个函数还是自身)。结果进入到新的函数之后再次if判断,结果符合条件就再次打印‘11’,然后执行环境再次被改变(这里叫C)。在新的执行环境内发现if不在满足,退出当前的执行环境(这里是从C退出),把控制权交给之前的执行环境(这里交给的是B不是A,然后打印‘22‘),而B在这时也不在满足条件就在交给最初的A,然后A继续接下来的执行打印’22‘。

 

因此

这样上面的结果也就比较好理解了,只是函数里面有两个递归,当第一个递归把控制权交回到最开始的时候是第二个递归的开始,所以就会看到打印的结果跳来跳去,所以使用递归的时候一定要注意。

转载于:https://www.cnblogs.com/Dn9x/p/3517625.html

你可能感兴趣的文章
一次sql注入中转
查看>>
使用pd设计表的 多对多的中间表的设计方式, 有图有真相
查看>>
Spring注解详解
查看>>
OSGI API
查看>>
《转》Objective-C Runtime(4)- 成员变量与属性
查看>>
Rational Rose
查看>>
Webbrowser控件中屏蔽弹出脚本错误对话框
查看>>
华为交换机S5700系列配置通过STelnet登录设备示例
查看>>
error: The following untracked working tree files would be overwritten by merge: 错误解决
查看>>
ASP.NET MVC 3.0 HTML辅助方法
查看>>
linux shell命令行下操作mysql 删除mysql指定数据库下的所有表--亲测成功百分百测试通过--绝对可靠...
查看>>
嵌入式交叉编译环境搭建
查看>>
zabbix 编译
查看>>
linux 网络Socket实战
查看>>
大河奔流的精神 ——俞敏洪
查看>>
HTML5 划线,画圆
查看>>
<Linux> Xen虚拟机镜像的安装
查看>>
Python3.7安装PyQt5的方法
查看>>
出发去哪儿
查看>>
bootstrap3学习1:响应式布局layout
查看>>