[英]Javascript recursions. Why the following code works with .unshift() instead of .push()?
我的大脑认为我应该使用.push()
而不是.unshift()
但 freeCodeCamp 和我的控制台告诉我这是正确的做法。 我只是不明白为什么我的数字使用.unshift()
从 10 到 20,而使用.push()
20 到 10 ;
我阅读代码的方式:如果startNum
大于endNum
返回一个空数组。 否则,创建一个名为arr
的变量,并将每次代码运行时增加 1 的当前startNum
分配给它,并将其返回到数组中。
我究竟做错了什么?
function rangeOfNumbers(startNum, endNum) {
if (startNum > endNum) {
return [];
} else {
const arr = rangeOfNumbers(startNum + 1, endNum);
arr.unshift(startNum);
return arr;
}
}
console.log(rangeOfNumbers(10, 20));
控制台: (11) [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
unshift
将一个元素插入到数组的开头。
由于您是从startNum
迭代到endNum
,请考虑下一个递归调用:
const arr = rangeOfNumbers(startNum + 1, endNum);
arr.unshift(startNum);
return arr;
其中startNum
是 19, endNum
是 20。递归调用返回一个包含一个元素的数组: [20]
。 然后你需要在适当的位置插入19
元素。
为此,您需要在开头插入 19,以获得:
[19, 20]
所以,用unshift
在开头插入 19 。
如果您改用push
,那么从原来的[20]
,您会得到:
[20, 19] // 19 added to end
进而
[20, 19, 18] // 18 added to end
等等,顺序不对。
如果在递归调用之前插入元素,则可以使用push
。
function rangeOfNumbers(startNum, endNum, arr = []) { arr.push(startNum); if (startNum < endNum) { rangeOfNumbers(startNum + 1, endNum, arr); } return arr; } console.log(rangeOfNumbers(10, 20));
一种思考方式是想象递归调用已经正常工作。 所以rangeOfNumbers(11, 20)
会产生[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
。 所以const arr = rangeOfNumbers(startNum + 1, endNum)
意味着arr
是[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
。 现在您有了startNum
和arr
并且需要将它们组合起来。 push
会将startNum
添加到末尾。 unshift
正确地将它添加到开头。
但是当我们在这里时,我想建议一种更优雅的方式来表达相同的算法:
const rangeOfNumbers = (start, end) =>
start > end
? []
: [start, ... rangeOfNumbers (start + 1, end)]
我们有一个条件表达式,而不是if-else
语句。 我们不会在这个过程中改变像arr
这样的变量。 我认为它也更清晰地表达了算法。 当然口味可能会有所不同,而且,如果您只是在学习 JS,这可能涉及您尚未见过的语法。 但如果你确实理解它,你可能会同意我关于它的优雅。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.