递归javascript代码有问题吗?
我用javascript编写了以下简单的递归函数代码:递归javascript代码有问题吗?,javascript,recursion,Javascript,Recursion,我用javascript编写了以下简单的递归函数代码: function print(text) { if (!text) { throw 'No text in input !'; } console.log('print : '+text); } function stack(msg, stackSize) { stackSize++; print('Stack Entry '+stackSize); if (stackSiz
function print(text) {
if (!text) {
throw 'No text in input !';
}
console.log('print : '+text);
}
function stack(msg, stackSize) {
stackSize++;
print('Stack Entry '+stackSize);
if (stackSize < 4) {
stack(msg, stackSize);
} else {
print(msg);
}
print('Stack exit '+stackSize);
}
stack('foobar',0);
在对这段非常琐碎的代码大惊小怪之后,我仍然不明白堆栈出口值为什么在减小?,发生了什么事
stackSize
是函数参数,因此它存储在堆栈中,当函数从递归返回时,从堆栈访问该值,该值与调用函数时传递的值相同
从递归调用返回时,将弹出堆栈中最顶层的帧,并从中读取参数值函数参数存储在堆栈上,两个函数调用之间不共享这些参数,即使递归调用同一个函数也是如此
你所期待的
您从未声明过变量stackSize
,因此变量(参数)的范围仅在函数中。如果您声明变量而不将其作为参数传递,那么它将被共享
以下是您所期望的,因为变量是共享的,所以从递归调用返回时访问相同的值,并返回相同的值
var stackSize=0;
功能打印(文本){
如果(!text){
抛出“输入中没有文本!”;
}
console.log('打印:'+文本);
}
函数堆栈(msg){
stackSize++;
打印(“堆栈条目”+堆栈大小);
如果(堆栈大小<4){
堆栈(msg,stackSize);
}否则{
印刷品(味精);
}
打印(“堆栈出口”+堆栈大小);
}
堆栈(“foobar”,堆栈大小)代码>堆栈的基本功能是或先进先出
,这意味着堆栈上的任何东西最终都会首先从堆栈中出来,第一次推送最后出来,所以当递归函数上次调用时,值为4,完成执行,然后执行第三个堆栈函数,依此类推。这就是它的执行方式,事实上,这是显而易见的。当你有递归函数时,想想它们就像盒子里的盒子里的盒子一样。。。包装盒:
+-------------------------+
| 1 |
| +-------------------+ |
| | 2 | |
| | +----------------+| |
| | | 3 || |
| | | +-------------+|| |
| | | | 4 ||| |
| | | +-------------+|| |
| | +----------------+| |
| +-------------------+ |
+-------------------------+
它先进后出:
- 堆栈大小:1
- 堆栈大小:2
- 堆栈大小:3
- 堆栈大小:4
- 堆栈大小:4
- 堆栈大小:3
- 堆栈大小:2
- 堆栈大小:1
每次调用堆栈
时,都会进入调用堆栈的更深一层。您可以这样写下来,以查看您执行的函数调用:
stack('foobar',0);
print('Stack Entry 1');
stack('foobar',1);
print('Stack Entry 2');
stack('foobar',2);
print('Stack Entry 3');
stack('foobar',3);
print('Stack Entry 4');
stack('foobar',4);
print('foobar');
print('Stack exit 4');
print('Stack exit 3');
print('Stack exit 2');
print('Stack exit 1');
如@Tushar所述,stackSize
的值在从递归调用返回时从堆栈中检索。您可以在每次调用之间共享stackSize
,方法是将调用作为一个包含一个元素的数组传递,请参见下面的我的代码片段:
功能打印(文本){
如果(!text){
抛出“输入中没有文本!”;
}
console.log('打印:'+文本);
}
函数堆栈(消息、堆栈大小){
堆栈大小[0]++;
document.write('Stack Entry'+stackSize[0]+'
');
if(堆栈大小[0]<4){
堆栈(msg,stackSize);
}否则{
印刷品(味精);
}
document.write('Stack exit'+stackSize[0]+'
');
}
堆栈('foobar',[0])
这很有意义,因为每个调用都会等待其子调用完成,然后再打印“stack exit”。您是否希望stack size
在对stack
的每个调用之间共享?不会的。它们都有自己的变量本地副本。stackSize
是函数stack
中的本地变量吗?很好的视觉表现+1@Tushar学分归我的高中计算机科学老师——我也对这种表现感到惊讶这是伟大的爱奥尼卡。。。一幅好的图画永远是你能抓住这个想法的最好的东西@是的,永远!很乐意帮忙<代码>:-)
这个
是怎么回事?我添加了
标签,在每个输出行之后添加了回车符。我发现在代码片段中快速格式化输出是最简单的方法,但如果您知道更好的方法,我愿意听取您的建议。但是为什么您要编写
而不是
?这没有道理!br
元素没有结束标记!将我的示例更改为使用
而不是`,请参阅。
stack('foobar',0);
print('Stack Entry 1');
stack('foobar',1);
print('Stack Entry 2');
stack('foobar',2);
print('Stack Entry 3');
stack('foobar',3);
print('Stack Entry 4');
stack('foobar',4);
print('foobar');
print('Stack exit 4');
print('Stack exit 3');
print('Stack exit 2');
print('Stack exit 1');