为什么每次进行递归迭代时我的变量都会重新初始化为其原始值,但以某种方式保留新值

所以我刚刚在 AlgoExpert 上解决了一个代码挑战,我试图更深入地了解我的代码为什么起作用,所以我使用 PythonTutor 来可视化代码的执行,我很想知道为什么每次递归调用使 arraySum 重新初始化为 0,但以某种方式保留了之前由数组中元素总和组成的值。

这是我解决的问题

为什么每次进行递归迭代时我的变量都会重新初始化为其原始值,但以某种方式保留新值

这是我的代码:

function productSum(array,multiplier=1) {
    let arraySum = 0;
    array.forEach(el => Array.isArray(el) ? arraySum+=productSum(el,multiplier+1) : arraySum += el)
    return arraySum * multiplier
}

productSum([5,2,[7,-1],3,[6,[-13,8],4]])

这是 PythonTutor 中可视化的链接

mengzai8888 回答:为什么每次进行递归迭代时我的变量都会重新初始化为其原始值,但以某种方式保留新值

当您意识到 (50000,5) 的每次执行都有自己的 productSum 变量时,情况就变得很清楚了。尽管名称每次都相同,但它确实是一个与其他(在递归树中)碰巧具有相同名称的变量无关的变量。

每次进行递归调用时,调用者的arraySum都会在一个堆栈帧上结束,递归调用返回时从那里恢复,然后将返回的值添加到自己的{{1} }.

因此一个值在从递归中回溯时正在累积,所有这些不同的 productSum 变量都在携带中间结果方面发挥着很小的作用,直到它返回给调用者,调用者进一步累积它,。 ..等

,

您的算法包含递归调用:您的 productSum 有时会在数据结构的更深层次上使用不同的参数再次调用自身。

每个调用都有自己的调用框架,具有自己独特的作用域。您的 let arraySum = 0 是在函数(范围)内定义的,因此除了其他调用之外,每个调用都有自己的 arraySum(初始化为 0)。

我制作了另一个图表,其中每个框/椭圆形都是一个调用框架:

Call visualization

没有显示乘法部分。

每个调用帧都有自己的范围和自己的 array/multiplier/arraySum 变量。每次调用都以 arraySum = 0 开头,使用 .forEach 添加到此变量,然后返回存储在变量中的值。这就是为什么在 Python 可视化工具中您有时会看到 arraySum 变为 0。并不是某个地方的实际 arraySum 变成了 0,而是因为您正在查看一个全新的函数调用,就在 let arraySum = 0 语句之后。

更改一个作用域中的 arraySum 不会影响另一个作用域的 arraySum,即使两个作用域都针对同一个函数(但函数调用不同!)。

本文链接:https://www.f2er.com/4671.html

大家都在问