我有一个非常受开发人员欢迎的算法练习,它返回:steps(3)######steps(5)###############我正在研究以递归方式开发的版本。下面的代码工作正常。function steps(n, row = 0 , stair = '') { if(n === row) { return; } if(n === stair.length) { console.log(stair) return steps(n, row + 1) } if (stair.length <= row) { stair += '#'; } else { stair += ' ' } steps(n, row, stair)}steps(3)我唯一的疑问与这部分代码中“返回”的重要性有关: if(n === stair.length) { console.log(stair) return steps(n, row + 1) // <--- this 'return' }如果我删除'return',像这样:if(n === stair.length) { console.log(stair) steps(n, row + 1) // <-- without the return}这会在控制台上生成一个循环错误:超出最大调用堆栈大小我想了解为什么会发生这种情况。我仍然没有太多的递归函数练习。
3 回答

慕桂英4014372
TA贡献1871条经验 获得超13个赞
它中断是因为您的代码在 row === n 时终止。那条线是唯一改变行的地方。没有它,代码将产生如下输出:
#
#
#
#
#
...
由于您在递归函数中处理此问题,因此 javascript 在它变得无限深之前会用完堆栈帧。

烙印99
TA贡献1829条经验 获得超13个赞
有两种方法可以考虑递归函数。首先是实际查看实际发生的情况——也就是说,查看一个示例并通过注意对函数的所有调用来“展开” steps
。这很安全,也很容易。
第二种方式更“神奇。在这种思维方式中,您不会考虑“大局”或考虑递归函数的多次调用。相反,您形成了一个连贯的想法,即您的递归函数应该接受什么作为参数和它应该返回什么。然后,您始终可以按照您认为它应该工作的方式使用该函数来编写递归函数的主体。这可能会更加令人困惑,但是一旦您“获得”它,它就会非常优雅并且是更有用的思维方式。
让我们在这里使用第一种思维方式,因为它可能更容易。steps
你能告诉我按顺序调用了多少次以及使用哪些参数?例如,第一个调用是steps(5, 0, '')
. 那么,第二次调用steps
会发生什么?按照这些步骤(呵呵),您应该会看到问题所在。
添加回答
举报
0/150
提交
取消