Javascript - 子块中的变量重新定义 // 变量阴影

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

我正在尝试了解 Javascript 如何处理在当前作用域的子块中重新声明 let 变量。

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.

如果我们尝试这样做,它会按预期正常工作:

function letTest() {
  let x = 1;

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

再举个例子。现在我使用 for 子块将新值分配给 0let 变量,然后执行 for 循环。 这也按预期工作。

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
}

但是当我们在 for 子块中使用关键字 let 重新声明并为同一个变量 x 分配新值时会发生什么:

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
}

这里是什么机制在起作用,到底发生了什么?

为什么let x = 5的值没有变,为什么现在有2个let同名变量?

let 语句创建块作用域变量。

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 语句创建函数作用域变量。

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)
}

我相信我在这里找到了答案:

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.

还有这里:

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...