JavaScript递归countdown函数中未显式声明数组的arr为何能调用unshift方法
问题原理解答
function countdown(n) { if (n < 1) { return []; } else { const arr = countdown(n - 1); arr.unshift(n); return arr; } }
核心原因是这段代码里的arr永远是被合法的数组类型赋值的,不存在未赋值的情况,具体逻辑拆解如下:
- 所有递归调用最终都会走到
n < 1的终止分支,这个分支会显式返回一个空数组[],这是所有上层arr变量的初始值来源 - 非终止分支的
arr变量赋值的是countdown(n - 1)的返回值,而这个函数不管走哪个分支,最终返回值一定是数组类型:要么是终止分支返回的空数组,要么是上一层递归处理完成后返回的填充了数值的数组
举个实际调用的例子,比如执行countdown(2),完整执行顺序是:
- 执行
countdown(2),n=2不满足终止条件,需要先执行countdown(1)拿到返回值 - 执行
countdown(1),n=1不满足终止条件,需要先执行countdown(0)拿到返回值 - 执行
countdown(0),n=0满足终止条件,返回空数组[] - 回到
countdown(1)的执行逻辑,把countdown(0)返回的[]赋值给arr,调用unshift(1)后arr变成[1],返回[1] - 回到
countdown(2)的执行逻辑,把countdown(1)返回的[1]赋值给arr,调用unshift(2)后arr变成[2, 1],返回结果
你之前手动调用unshift报错,是因为你测试的变量是未赋值的undefined类型,和这段代码里arr永远被数组赋值的情况完全不同。
内容的提问来源于stack exchange,提问作者Erin Fleming
相关产品推荐
相关产品推荐

