Javascript递归减法

sla*_*arp 21 javascript

例1

function x(num) {
  if (num == 0) {
   return 1;
  }
  else {
   return (num * x(num - 1));
 }
}

x(8);
Run Code Online (Sandbox Code Playgroud)

8*7*6*5*4*3*2*1

结果是预期的40320

例2

function x(num) {
  if (num == 0) {
   return 0;
  }
  else {
   return (num + x(num - 1));
 }
}

x(8);
Run Code Online (Sandbox Code Playgroud)

8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0

结果是预期的36

例3

function x(num) {
  if (num == 0) {
   return 0;
  }
  else {
   return (num - x(num - 1));
 }
}

x(8);
Run Code Online (Sandbox Code Playgroud)

8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0

结果是4

有人可以解释原因吗?

答案不应该是-20?

Seb*_*mon 18

您的功能计算基本上是从右到左:

  8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0
= 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1
= 8 - 7 - 6 - 5 - 4 - 3 - 1
= 8 - 7 - 6 - 5 - 4 - 2
= 8 - 7 - 6 - 5 - 2
= 8 - 7 - 6 - 3
= 8 - 7 - 3
= 8 - 4
= 4
Run Code Online (Sandbox Code Playgroud)

这是因为每次x递归调用函数时,都会尝试评估最右边的表达式.

实际上,"堆栈"看起来像这样:

  8 - x(8 - 1)
= 8 - (7 - x(7 - 1))
= 8 - (7 - (6 - x(6 - 1)))
= 8 - (7 - (6 - (5 - x(5 - 1))))
= 8 - (7 - (6 - (5 - (4 - x(4 - 1)))))
= 8 - (7 - (6 - (5 - (4 - (3 - x(3 - 1))))))
= 8 - (7 - (6 - (5 - (4 - (3 - (2 - x(2 - 1)))))))
= 8 - (7 - (6 - (5 - (4 - (3 - (2 - (1 - x(1 - 1))))))))
= 8 - (7 - (6 - (5 - (4 - (3 - (2 - (1 - 0)))))))
= 8 - (7 - (6 - (5 - (4 - (3 - (2 - 1))))))
= 8 - (7 - (6 - (5 - (4 - (3 - 1)))))
= 8 - (7 - (6 - (5 - (4 - 2))))
= 8 - (7 - (6 - (5 - 2)))
= 8 - (7 - (6 - 3))
= 8 - (7 - 3)
= 8 - 4
= 4
Run Code Online (Sandbox Code Playgroud)

JavaScript对"纯"减法的评估是:

8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0; // -20
Run Code Online (Sandbox Code Playgroud)


Spe*_*rek 17

因为你的功能是从右到左有效地计算:

8 - (7 - (6 - (5 - (4 - (3 - (2 - (1 - 0))))))) => 4
Run Code Online (Sandbox Code Playgroud)

并不是:

8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0 => -20
Run Code Online (Sandbox Code Playgroud)