我在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
在对这个非常简单的代码敲打之后,我仍然没有为什么堆栈退出值正在递减?
答案 0 :(得分:12)
这就是它的执行方式,而且它实际上是显而易见的。当你有递归函数时,想想它们就像盒子里的盒子一样......在盒子里:
+-------------------------+
| 1 |
| +-------------------+ |
| | 2 | |
| | +----------------+| |
| | | 3 || |
| | | +-------------+|| |
| | | | 4 ||| |
| | | +-------------+|| |
| | +----------------+| |
| +-------------------+ |
+-------------------------+
首先进入,然后出去:
答案 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 Out或First 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
,请参阅下面的代码段:
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;