简体   繁体   中英

Javascript - variable re-delcaring in the sub-block // Variable Shadowing

I am trying to understand how Javascript handles re-declaring of the let variable in the sub-block of the current scope.

let - JavaScript | MDN says:

Variables declared by let have their scope in the block for which they are defined, as well as in any contained sub-blocks.

If we try this, it works fine as expected:

function letTest() {
  let x = 1;

  for(var i = 0; i < 1; i++) {
    console.log(x);  // logs - 1
  }
}

Another example. Now I use the for sub-block to assign a new value to let variable of 0 and go through the for loop. As well this works as expected.

function letTest() {
  let x = 5;
  console.log(x);  // logs – 5

  for( x = 0; x < 12; x++) {
    console.log(x);  // logs – 0, 1, 2, 3, 4, 5, 6, … 10, 11
  }

  console.log(x);  // logs - 12
}

But what happens when we re-declare and assign new value to the same variable x by using keyword let inside of the for sub-block :

function letTest() {
  let x = 5;
  console.log(x);  // logs – 5

  for( let x = 0; x < 12; x++) {
    console.log(x);  // logs – 1, 2, 3, 4, 5, 6, … 10, 11
  }

  console.log(x);  // logs - 5
}

What mechanism is here at work and what exactly happened?

Why is the value of let x = 5 not changed, why is there now 2 let variables with the same name?

The let statement creates a block scope variable.

function letTest() {
  let x = 5;
  console.log(x);  // x = 5 (same 'x')

  for(let x = 0; x < 12; x++) {
    console.log(x);  // x = 1, 2, …, 10, 11 (different 'x')
  }

  console.log(x);  // x - 5 (same 'x')
}

while var statement creates a function scope variable.

function varTest() {
  var x = 5;
  console.log(x);  // x = 5

  for(var x = 0; x < 12; x++) {
    console.log(x);  // x = 1, 2, …, 10, 11
  }

  console.log(x);  // x = 12 ('x' from the for-loop)
}

I deleted my previous answer because I misread your question.

Try running the following functions in your browser (chrome dev tools preferrably):

function letTest() {
   debugger;
   for(var i=0; i<2; i++) {
     //some code here
   }
}

At the debugger step, var will appear as 'i=undefined' even though it is initially defined in the for-loop. This is because it is scoped to the execution context which in this case is the function letTest. Since it is available here, it will also be available after the for-loop block.

function letTest() {
   debugger;
   for(let i=0; i<2; i++) {
     //some code here
   }
}

At the debugger step, i is not available because it is scoped to the block (and it's sub-blocks) , which is the for-loop.

function letTest() {
   let i=100
   for(i=0; i<2; i++) {
     //some code here
   }
}

Since let is available within it's own block and sub-blocks (which would be the for-loop), it's initial value is changed from 100 to 0, and then to 2 after the for-loop is finished.

function letTest() {
   let i=100
   for(let i=0; i<2; i++) {
     //some code here
   }
}

Since you are redeclaring let in a block, the 'i' here will have block scope as seen in the second example above. Since it has block scope, it is not available outside of the block.

I believe I found the answer here:

Demystifying JavaScript Variable Scope and Hoisting

In JavaScript, variables with the same name can be specified at multiple layers of nested scope. In such case local variables gain priority over global variables. If you declare a local variable and a global variable with the same name, the local variable will take precedence when you use it inside a function. This type of behavior is called shadowing. Simply put, the inner variable shadows the outer.

and here as well:

https://stackoverflow.com/a/11901489/6375464

In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. This outer variable is said to be shadowed...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM