在javascript中使用函数堆栈来调用非递归方法

时间:2016-01-28 08:33:52

标签: javascript

我想使用非递归方法重复调用函数。我得到了以下非递归方法的示例:

function foo(i) {
  if (i < 0)
    return;

  console.log('begin:' + i);
  foo(i - 1);
  console.log('end:' + i);
}

foo(3);
<!-- this is to make console output visible -->
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

并提供以下输出:

begin:3
begin:2
begin:1
begin:0
end:0
end:1
end:2
end:3

任何人都可以让我明白为什么要打印以下内容:

end:0
end:1
end:2
end:3

甚至函数也从行foo(i - 1);

返回

3 个答案:

答案 0 :(得分:2)

由于代码从顶部执行到底部,当您在函数内部调用函数时,它并不意味着停止执行父函数。它调用内部函数和内部函数调用内部函数等。直到最深函数返回值的情况下,值为最深函数的undefined

所以打印

begin:3
begin:2
begin:1
begin:0

此时达到了最深的函数,它返回undefinedreturn;)并且它上升,之前的函数在undefined之前有i=0,所以函数的执行完成了它的气泡调用内部函数后执行其余代码。结果:

end:0
end:1
end:2
end:3

答案 1 :(得分:0)

嗯,它是一个递归函数,因为函数在其定义块中调用自身。

foo(3) : ['begin:3', foo(2), 'end:3']
foo(2) : ['begin:2', foo(1), 'end:2']
foo(1) : ['begin:1', foo(0), 'end:1']
foo(0) : ['begin:0', foo(-1), 'end:0']
foo(-1) : []

如果你把所有内容放在一起,你就得到了你正在描述的输出。想象一下它就像matryoshka doll ......

让我们检查最后3行(为简单起见,我省略了换行符):

  • foo(-1)没有输出
  • foo(0)提供'begin:0' + foo(-1) + 'end:0'

    = begin:0 end:0

  • foo(1)提供'begin:1' + foo(0) + 'end:1'

    = begin:1 begin:0 end:0 end:1

答案 2 :(得分:0)

解决方案是使用处理队列而不是函数调用堆栈。然后按顺序调用函数foo而不是递归调用。

var q=[3]
function foo(x){
  ...
  q[q.length] = x-1//instead of foo(x-1)
  ...
}
while(q.length){foo(q.shift())}