Home > OS >  JavaScript Local Primitive Variable Re-assignment in Recursive Function
JavaScript Local Primitive Variable Re-assignment in Recursive Function

Time:10-08

I have a recursive function like below

function dfs(row, col) {
  if (grid[row][col] === 0) return true;
  let result = grid[row][col] === 2;
  grid2[row][col] = 0;

  let up = down = left = right = true;      // <--- problematic line

  if (row > 0) up = dfs(row-1, col);
  
  if (row < m-1) down = dfs(row 1, col);
  // down === false here
  
  if (col > 0) left = dfs(row, col-1);
  // down === false here still
  
  if (col < n-1) right = dfs(row, col 1);
  // down === true ??  

  return up && down && left && right && result;
}

I notice that during execution, at some point down = dfs(row 1, col) will assign a false value to down, but 2 lines below after right = dfs(row, col 1) somehow down becomes true again.

This mutation would make sense to me if down was a non-primitive variable like Array or Object and we were passing it around across recursive calls, however it's just a boolean. Furthermore, changing the problematic line to below fixes the problem. (i.e. down no longer gets re-assigned to true)

let up = true, down = true, left = true, right = true;

Does anyone know why this re-assignment happens here? Thanks!

CodePudding user response:

The following line:

let up = down = left = right = true;

only declares up. down, left, right are assigned from global scope and can get updated by any recursion step since they are not local variables.

CodePudding user response:

That let declaration does not do what you think it does. (Well, what I think you think it does.)

The = in a let (or var or const) declaration works like this:

let a = <expression>;

Only one variable is declared, a. You can use the assignment operator in that <expression>, but it will not cause any other variables to be declared. The variables would have to exist in some enclosing scope, or else (if you're not in "strict" mode) they will become implicit global variables.

In your statement,

let up = down = left = right = true;

the variable up is the only one declared. To get what I think you want, you'd need

let up, down, left, right;
up = down = left = right = true;

That will create all four variables in the current scope, and then the subsequent assignment will make them all true.

  • Related