需要帮助理解这个递归函数
Need help understanding this recursion function
我正在尝试学习递归,我在网上找到了这个示例函数。我不太明白这里到底发生了什么。最让我感到困惑的部分是,我在最后一个块(其中参数减少为2)中放置了两个警报命令,以查看当它到达这一点时"first"answers"second"的值是什么。出现的值是"4"answers"3",我在返回之前将这两个值相加。结果是7。然后实际返回的是相同的方程,它给出的答案是10。有谁能给我解释一下这是如何工作的,它是如何最终到达10的?
function sum() {
var args = Array.from(arguments);
var first = args[0];
var second = args[1];
if(args.length === 2) {
alert("first:" + first + " second:" + second );
alert("Sum: " + (first+second) ) //this alerts 7
return first + second; //returned value is 10
}
return first + sum.apply(null, args.slice(1));
}
var results = sum(1,2,3,4);
console.log(results);
第一次通过sum,它获取1和2,但args。长度== 4,所以它返回1 + 还有待确定的值。
要找到仍有待确定的,该函数再次调用sum(递归),但将第一个元素切片,因此我们剩下2,3,4这次,它捕获了2和3,但是是参数。长度== 3,所以它表示还有待决定的东西是2 + 另一个。
要找到另一个,函数再次调用sum(递归),但再次切掉第一个元素。上次是2,3,4,所以这次是3,4
这次是args。长度== 2,所以它进去,加起来3+4 == 7。然后你的警报第一次被调用因为这是它第一次经过这段代码。最后它返回7。这是三层深。
唷!现在我们知道 = 7,这意味着还有待决定 = 2 + = 2 + 7 = 9,所以我们将返回它。这是两层的深度
最后,我们返回1 + *一个有待决定的数= 1 + 9 = 10,来自sum()的第一层
它警告7,然后返回10的原因是因为你的警告只在参数。长度== 2
如果你所阅读的特定函数是一堆垃圾,这并没有什么帮助。你不能很好地理解它不是你的错。
首先,您找到的函数不是总函数 -意思是,它不会对其域的所有输入产生合理的结果。
sum();
// RangeError: Maximum call stack size exceeded
sum(1);
// RangeError: Maximum call stack size exceeded
这太荒谬了。我们可能期望sum()
返回0
(可能是NaN
),但sum(1)
应该肯定返回1
。
其次,这个函数使用的是Array.from
,这使它处于ES6+时代的代码…
function sum() {
// are you f*$@ing joking me??
var args = Array.from(arguments);
…使用Array.from
,但仍然使用旧的arguments
对象?哇。
不管怎样…*wretch*, *gag* -这是一个糟糕的函数*puke*你不应该关注它。
考虑以下sum
函数实现。我保证你将能够毫不费力地理解这些。
function sum(numbers) {
if (numbers.length === 0)
return 0;
else
return numbers[0] + sum(numbers.slice(1));
}
console.log(sum([])); //= 0
console.log(sum([1])); //= 1
console.log(sum([1,2,3,4,5,6,7,8,9])); //= 45
它的工作方式只有有一点不同,接受一个数组的数字,而不是可变参数。
// sum must be called like this now
sum([1,2,3,4,5,6,7,8,9]);
// instead of:
sum(1,2,3,4,5,6,7,8,9);
好吧,也许支持可变接口是必要的。还有更好的方法——特别是如果你可以使用ES6
// ES6 using spread syntax
function sum(n,...ns) {
if (n === undefined)
return 0;
else
return n + sum(...ns);
}
console.log(sum()); //= 0
console.log(sum(1)); //= 1
console.log(sum(1,2,3,4,5,6,7,8,9)); //= 45
好吧,也许你不能用ES6。还有一个更好的方法,使用es6之前版本
// ES5; relying upon old arguments object
function sum(/*numbers*/) {
if (arguments[0] === undefined)
return 0;
else
return arguments[0] +
sum.apply(null, Array.prototype.slice.call(arguments, 1));
}
console.log(sum()); //= 0
console.log(sum(1)); //= 1
console.log(sum(1,2,3,4,5,6,7,8,9)); //= 45
- 递归函数中断
- 将jQuery对象传递到setTimeout递归函数中
- 对象与递归函数的比较
- 循环内部的递归函数未按预期工作
- 递归函数返回不正确
- 递归函数编程困境
- 给定一个带有数字的数组,我如何编写一个递归函数,当 2 个元素加起来为一个目标时,它会在数组中查找索引
- 返回不会退出 javascript 中的递归函数
- jquery递归函数转换为非递归函数
- AngularJS,promise带有递归函数
- 如何停止此递归函数
- 如何将下面的递归函数转换为纯函数
- jQuery setTimeout ajax递归函数在即时消息程序中短时间后抛出错误
- Javascript递归函数引用了这一点
- 如何将这个递归函数转换为迭代函数
- jQuery递归函数调用和Javascript之间有区别吗;s setInterval
- 从javascript中的递归函数获取undefined
- 将递归函数转换为异步 CPS 实现 (javascript)
- 我怎样才能把它变成一个循环,而不是一个递归函数
- 在Javascript的递归函数中使用正则表达式进行解析