Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
递归javascript代码有问题吗?_Javascript_Recursion - Fatal编程技术网

递归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

我用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 (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');