递归javascript代码的麻烦?

时间:2015-10-02 08:49:27

标签: 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 (stackSize < 4) {
        stack(msg, stackSize);
    } else {
        print(msg);
    }
    print('Stack exit '+stackSize);
}

stack('foobar',0);

产生以下输出:

print : Stack Entry 1
print : Stack Entry 2
print : Stack Entry 3
print : Stack Entry 4
print : foobar
print : Stack exit 4
print : Stack exit 3
print : Stack exit 2
print : Stack exit 1

在对这个非常简单的代码敲打之后,我仍然没有为什么堆栈退出值正在递减

5 个答案:

答案 0 :(得分:12)

这就是它的执行方式,而且它实际上是显而易见的。当你有递归函数时,想想它们就像盒子里的盒子一样......在盒子里:

 +-------------------------+
 | 1                       |
 |   +-------------------+ |
 |   | 2                 | |
 |   | +----------------+| |
 |   | | 3              || |
 |   | | +-------------+|| |
 |   | | | 4           ||| |
 |   | | +-------------+|| |
 |   | +----------------+| |
 |   +-------------------+ |
 +-------------------------+

首先进入,然后出去:

  • stackSize:1
    • stackSize:2
      • stackSize:3
        • stackSize:4
        • stackSize:4
      • stackSize:3
    • stackSize:2
  • stackSize:1

答案 1 :(得分:3)

发生了什么

stackSize是函数参数,因此它存储在堆栈中,当函数从递归返回时,从堆栈访问该值,它与调用函数时传递的值相同。 / p>

从递归调用返回时,弹出堆栈中最顶层的帧,并从中读取参数值。 函数参数存储在堆栈上,即使在递归调用相同的函数时,两个函数调用之间也不是 shared

您的期望

您从未声明变量stackSize,因此变量(参数)的范围仅在函数中。如果声明变量并且不将其作为参数传递,则将共享该变量。

以下是您所期望的,因为该变量是共享的,所以在从递归调用返回时访问相同的值并返回相同的值。

var stackSize = 0;
function print(text) {
  if (!text) {
    throw 'No text in input !';
  }
  console.log('print : ' + text);
}

function stack(msg) {
  stackSize++;
  print('Stack Entry ' + stackSize);
  if (stackSize < 4) {
    stack(msg, stackSize);
  } else {
    print(msg);
  }
  print('Stack exit ' + stackSize);
}

stack('foobar', stackSize);

答案 2 :(得分:1)

堆栈的基本是Last In First OutFirst In Last Out,这意味着堆栈上的任何东西最后都会从堆栈中出现,并且最后一次推送出来,所以当上次递归函数调用时,值为4,完成执行,然后执行第3个堆栈函数,依此类推。

答案 3 :(得分:1)

每次拨打stack时,您都会转到调用堆栈的更深层。您可以将其写下来,以查看您执行的函数调用:

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');

答案 4 :(得分:1)

如@Tushar所述,从递归调用返回时,从堆栈中检索stackSize的值。您可以通过将其作为包含一个元素的数组传递给每个调用之间共享stackSize,请参阅下面的代码段:

&#13;
&#13;
function print(text) {
  if (!text) {
    throw 'No text in input !';
  }
  console.log('print : ' + text);
}

function stack(msg, stackSize) {
  stackSize[0] ++;
  document.write('Stack Entry ' + stackSize[0] + '<br/>');
  if (stackSize[0] < 4) {
    stack(msg, stackSize);
  } else {
    print(msg);
  }
  document.write('Stack exit ' + stackSize[0] + '<br/>');
}

stack('foobar', [0]);
&#13;
&#13;
&#13;

相关问题