递归中自增操作执行逻辑解析:为何JS代码输出为25而非15?
递归中全局变量自增的逻辑误区分析
先看你提供的代码:
let x = 0; function func(n) { if (n > 0) { x++; return func(n - 1) + x; } return 0; } console.log(func(5));
你的推导错误在于,误以为func(n-1)执行时,后面的x是当前调用自增后的数值,但**x是全局变量,所有递归调用都会修改它,且+x是在func(n-1)完全执行完毕后才会读取x的当前值**。
正确的执行流程拆解
- 调用
func(5):n>0,x自增为1,随后执行func(4) + x(此时x的取值要等func(4)执行完才会确定) - 调用
func(4):n>0,x自增为2,执行func(3) + x - 调用
func(3):x自增为3,执行func(2) + x - 调用
func(2):x自增为4,执行func(1) + x - 调用
func(1):x自增为5,执行func(0) + x - 调用
func(0):直接返回0,开始回溯计算
回溯阶段:
func(1) = 0 + x→ 此时x已经是5,所以func(1)=5func(2) = func(1) + x→ 5 + 5 = 10(x仍为5,没有新的自增操作)func(3) = func(2) + x→ 10 + 5 = 15func(4) = func(3) + x→ 15 + 5 = 20func(5) = func(4) + x→ 20 + 5 = 25
最终输出25,和实际运行结果一致。
如何得到你预期的15
如果想要每一步递归都使用当前调用自增后的x值,需要避免使用全局变量,把x作为参数传递(形成局部作用域的变量):
function func(n, x = 0) { if (n > 0) { x++; return func(n - 1, x) + x; } return 0; } console.log(func(5)); // 输出15
此时每一层递归的x都是独立的局部值,不会被后续调用修改,符合你最初的推导逻辑。
内容的提问来源于stack exchange,提问作者Abdelazem Rabie
相关产品推荐
相关产品推荐

