这个带递归的双函数调用背后的逻辑是什么?

时间:2017-08-14 21:31:01

标签: javascript function recursion

我目前拥有控制台日志,<vector xmlns:android = "http://schemas.android.com/apk/res/android" android:width = "24dp" android:height = "24dp" android:viewportHeight = "24.0" android:viewportWidth = "24.0"> <path android:fillColor = "#00000000" android:pathData = ""/> </vector> 似乎从10倒数到1(这很有意义),但在此之后,countdown似乎在way的最终结果中加了15 1}} 9次,但为了实现这一点,我想在每个countdown循环之后调用countdown,但每个都跟踪自己的way?关于这个逻辑的原因和时间的任何澄清都会有所帮助 - 谢谢!

value

3 个答案:

答案 0 :(得分: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
  • 开始倒计时
  • 值&gt; 0所以运行way(countdown(9)) //注意:首先执行倒计时。
  • 倒计时以9
  • 运行
  • 值&gt; 0所以运行way(countdown(8)) //注意:首先执行倒计时。
  • ...
  • ...
  • ...
  • value == 0,返回0(倒计时):执行way
  • 方式返回0 + 15
  • 方式返回15 + 15
  • 方式......等等。

正如澄清为什么这种逻辑会有所帮助;我认为这里有一个值得学习的教训。

在应用递归时,基本上有2个相关的函数调用位置:

  1. 在递归调用
  2. 之前定位
  3. 递归调用
  4. 之后定位

    我将把它作为一个练习,为什么这有任何相关性。

答案 1 :(得分:0)

如上所述,value是任一函数中的局部变量,因此始终绑定到任一函数的范围。除了期望那里的太多复杂性之外,它实际上并没有造成混乱。 ;)

行为来自countdown()被递归调用,并且调用way()必须等到递归调用countdown()返回。但是直到countdown()的递归停止在值0才最终返回时才会发生这种情况。之后再次调用countdown(),但由于countdown()是递归调用的,而且这是countdown()的所有调用中的冒泡,因此有多个way()调用结果从countdown()调用way()返回结果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,然后再进一步冒泡。

实际上,只有一次递归。

答案 2 :(得分:0)

首先,代码开始使用参数countdown

开始执行您对value=10的第一次调用
  1. Stack:[]
  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,然后从堆栈{弹出} {1}}等于countdown(1)way(countdown(0)),然后打印出way(15),依此类推......
  7. 希望这很清楚