帮助理解递归和指数-JavaScript



我是新手,一直在努力在我的大脑中合理化这一点,但似乎无法理解。首先,许多人会使用简单的"for"循环来识别:

function power(base, exponent){
var result = 1;
for(var i = 0; i < exponent; i++){
if(exponent == 0)
return 1;
else
result *= base;
};
return result;
}

在本节中,我将阅读有关递归的内容,并讨论函数如何在不导致堆栈溢出的情况下调用自己。代码如下:

function power(base, exponent) {
if (exponent == 0)
return 1;
else
return base * power(base, exponent - 1);
}
console.log(power(2, 3));

我遇到的问题是理解它的实际工作方式,我认为这是正在发生的:

在它移动到第一个"if"语句之后,它移动到"else",并调用自己返回到if语句的顶部,每次减1,直到它达到0,此时它只返回"result"。是这样吗?还是我完全错过了什么?

好的,让我们分步骤来看:

您呼叫pow(2, 3)

首先,它运行以下代码:

function power(base, exponent) {
if (exponent == 0)
return 1;
else
return base * power(base, exponent - 1);
}

代入值:

function power(base /* 2 */, exponent /* 3 */) {
if (3 == 0)
return 1;
else
return 2 * power(2, 2);
}

为了加快这个答案,我将从现在起把它放在一张表中:

第一个呼叫解析为

1)2 * power(2, 2);

2)2 * (2 * power(2, 1))

3)2 * (2 * (2))

(在最后一个上,指数是1,所以它返回基数或2)

每次循环时,它都会根据基本对答案进行计时

就像循环一样,在这个例子中,

2 * (2 * (2)) === 8,所以power(2, 3) === 8

递归不是迭代的,它不会让函数返回任何位置,它会让函数启动自己的另一个实例来进一步解决其结果。

让我们考虑一个更简单的例子。这个函数从给定的数字倒计时到0,每次被5:整除时都会大喊"FIVE"和当前数字

function foo(anumber)
{
if(anumber <= 0)
{
console.log("Reached 0, done.");
}
else
{
if(anumber % 5 == 0)
{
console.log("FIVE - " + anumber);
}
foo(anumber - 1);
}
}

foo检查该数字是否等于或低于零,如果不是,则检查其是否可被5整除,如果是,则它会大叫,并且不管怎样,它都会启动另一个foo来检查低于1的数字。当foo的实例最终达到0时,链不会继续,堆栈会崩溃。

递归的这种简单使用几乎只在函数式编程中使用,这表明变量更改和迭代循环都对代码不利,并导致混乱。一般来说,使用循环更简单,通常RAM效率更高。

递归只有在更复杂的例子中才能发挥其潜力,但我相信,有了基本的解释,理解这些不会成为问题。

最新更新