2016-01-28 98 views
-3

我想使用非递归方法重复调用一个函数。我有一个非递归方法,下面的例子:在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 

Ev从函数foo(i - 1);返回

+8

这是一个递归函数............... –

+4

你为什么认为它是非递归的? – hindmost

+0

https://developer.mozilla。org/en-US/docs/Web/JavaScript/Guide/Functions –

回答

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

+0

但它没有打印开始:3end:3begin:2end:2 ......... ???/ –

+0

它以相反顺序打印'end's。 – putvande

+0

@putvande:不,它不是......仔细看看这些元素是如何组装成像一个matryoshka娃娃... – xmoex

0

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

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

这是一个答案?也许你应该解释一下。 – putvande

2

因为从顶部底部,执行的代码,当你调用一个函数内部功能,这并不意味着该父功能的执行停止。它调用内部函数和内部函数调用内部函数等。直到最深函数返回值的时刻您的值为最深函数的undefined

所以它打印

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

在这一点上最深的功能达到和它返回undefinedreturn;),它的上升,以前的功能未定义之前有i=0,这样的函数执行完毕,并冒泡调用内部函数后执行其余的代码。结果:

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