递归函数中JavaScript本地原始变量意外重赋值问题
递归DFS中布尔变量意外被修改的原因分析
问题的核心是链式赋值写法导致的变量作用域错误,和原始类型/引用类型的传递机制无关,具体原因如下:
错误写法的执行逻辑
你写的这行代码:
let up = down = left = right = true;
JavaScript会按从右到左的顺序执行赋值:
- 先将
true赋值给right,但right没有用let声明,会被隐式创建为全局变量(如果当前作用域没有同名变量的话) - 接着把
right的值赋值给left,left同样是全局变量 - 再赋值给
down,down也变成全局变量 - 最后将值赋值给
up,up是用let声明的函数局部变量
这就导致:所有递归调用的dfs函数,都会共享同一个全局的down、left、right变量。当后续递归调用(比如执行right = dfs(row, col+1)时的嵌套调用)修改这些全局变量时,上一层递归栈里的变量值会被直接覆盖。
对应你的代码场景
- 当执行
down = dfs(row+1, col)时,全局down被赋值为false - 执行
right = dfs(row, col+1)时,这个嵌套的dfs调用里又执行了let up = down = ...,会把全局down重新赋值为true - 回到上一层递归栈后,读取的
down已经是被修改后的全局变量值,所以出现了down从false变回true的现象
正确写法的作用
当你改成:
let up = true, down = true, left = true, right = true;
这里的每个变量都通过let声明为当前dfs函数的局部变量,每个递归栈帧都会拥有独立的变量副本,不会被其他递归调用干扰,因此不会出现值被意外覆盖的问题。
总结
原始类型(如布尔值)本身是值传递,不会在递归中被意外修改,但你的链式赋值写法错误地将变量提升到了全局作用域,导致不同递归调用共享同一个变量,才引发了这个问题。声明多个变量时,必须确保每个变量都由let/const明确声明,保证作用域正确。
内容的提问来源于stack exchange,提问作者DrinkPractical9526
相关产品推荐
相关产品推荐

