2017-08-14 121 views
0

我在哪里目前有控制台日志,countdown似乎从10倒数到1(这是有道理的),但在此之后,way似乎增加了15次到最终结果countdown 9次,但为了这种事情发生,我想象一下,在每个countdown循环之后,way被调用,但是每个都跟踪它自己的value?任何关于此逻辑的原因和时间的澄清将有所帮助 - 谢谢!这个递归函数调用的逻辑是什么?

var countdown = function(value) { 
 
    value = value - 1; 
 
    
 
    if (value == 0) { 
 
    return value; 
 
    } 
 
    
 
    console.log("loop 1 " + value); 
 
    return way(countdown(value)); 
 
}; 
 

 
function way(value) { 
 
    value = value + 15; 
 
    console.log(value); 
 
    return value; 
 
} 
 

 
countdown(10);

+0

清楚'value'是*参数*这两个函数。这不是全球价值。 – Pointy

+0

你可以发布控制台输出来澄清? – Stefan

+0

用调试器运行此操作,以及发生了什么。特别关注'价值'的位置。如果没有,请输入一些有用的'console.log'语句来跟踪执行流程。 – Prune

回答

0

为了理解这个递归码,这是最简单的按照程序计数器:

function way (value) { 
    value=value +15 
    console.log(value) 
    return value 
} 

countdown = function(value) { 
    value = value-1 
    if (value == 0) { 
     return value; 
    } 
    console.log("loop 1 " + value) 

    return way(
     countdown(value)); 
}; 

countdown(10); 
  • 开始倒计时10
  • 值> 0,所以运行way(countdown(9)) //注意:首先执行倒计时。
  • 倒计时运行9
  • 值> 0所以运行way(countdown(8)) //注意:倒数首先执行。
  • ...
  • ...
  • ...
  • 值== 0,返回0(在倒计时):执行way
  • 方式返回0 + 15
  • 方式返回15 + 15
  • 方式....等

作为论坛的澄清为什么这种逻辑将是有益的;我认为这里有一个教训值得学习。

基本上有应用递归的时候是2相关的函数调用的位置:

  1. 前递归调用
  2. 后递归调用定位定位

我会离开它作为一个行使为什么这有任何相关性。

0

如上面评论value是任一函数中的局部变量,因此总是与任一函数的范围相关联。除了期望太复杂之外,它实际上并没有造成混淆。 ;)

从递归调用countdown()开始,调用way()必须等到递归调用countdown()返回。但是,直到countdown()的递归停止在0值才会最终返回,这种情况才会发生。之后countdown()不是以后再调用,但由于countdown()被递归调用,这是通过有针对way()countdown()返回的结果多次调用称为月底这又与结果调用way()countdown()所有调用冒泡countdown()等等......好的,自己在这里有点困惑。

由于value不需要是复杂的,可能有助于消除它用于减少代码:

 
function countdown(value) { 
    if (value == 1) { return 0; } // bail out condition 

    console.log("loop 1 " + value) 
    return way(countdown(value - 1)); 
}; 

function way(value) { 
    console.log(value); 
    return value + 15; 
} 

countdown(10); 

way()是无相关性的递归的,因此可能会被取代的:

 
function countdown(value) { 
    if (value == 1) { return 0; } // bail out condition 

    console.log("loop 1 " + value) 
    return countdown(value - 1) + 15; 
}; 

countdown(10); 

由于递归,此代码深入9帧深度。然后它会冒泡堆栈,在每次通过的帧的结果再增加15个之后再继续冒泡。

所以实际上,只有一个递归。

0

起初,代码开始执行你到countdown第一次调用带有参数value=10

  1. 堆栈:[]
  2. 执行countdown(10)
  3. 堆栈:[countdown(10)]
  4. 然后执行way(countdown(9))和要执行此操作,JS首先评估countdown(9)
  5. 堆栈:[countdown(10),countdown(9)]等等,你可以想象,直到你达到countdown(0),然后开始从堆栈调用弹出。
  6. 首先调用堆栈解决,countdown(0) = 0,然后调用way(0),控制台日志0+15,然后countdown(0)最终返回15,然后从堆栈countdown(1)等于way(countdown(0)),这是way(15)弹出,然后打印出30,等等.. 。

希望这是足够