简体   繁体   English

Javascript-子块中的变量重新传送//变量阴影

[英]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. 我试图了解Javascript如何处理当前作用域子块中的let变量的重新声明。

let - JavaScript | let-JavaScript | MDN says: MDN说:

Variables declared by let have their scope in the block for which they are defined, as well as in any contained sub-blocks. let声明的变量的作用域在定义它们的块以及任何包含的子块中。

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. 现在,我使用for子块分配一个新值, let变量0进入for循环。 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 : 但是,当我们在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
}

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? 为什么let x = 5的值没有改变,为什么现在有2个同名的let变量?

The let statement creates a block scope variable. 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 statement creates a function scope variable. 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)
}

I deleted my previous answer because I misread your question. 我误读了您的问题,因此删除了以前的答案。

Try running the following functions in your browser (chrome dev tools preferrably): 尝试在浏览器中运行以下功能(最好使用chrome开发工具):

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. 在调试器步骤中,即使var最初是在for循环中定义的,var也会显示为“ i = undefined”。 This is because it is scoped to the execution context which in this case is the function letTest. 这是因为它的作用域是执行上下文,在这种情况下是函数letTest。 Since it is available here, it will also be available after the for-loop block. 由于此处可用,因此在for循环块之后也将可用。

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. 在调试器步骤中,i不可用,因为它的作用域为for循环的块(及其子块)。

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. 由于let在其自己的块和子块(可能是for循环)中可用,因此其初始值从100更改为0,然后在for循环完成后更改为2。

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. 由于您是在块中重新声明let,因此如上第二个示例所示,此处的“ i”将具有块作用域。 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 揭秘JavaScript变量作用域和提升

In JavaScript, variables with the same name can be specified at multiple layers of nested scope. 在JavaScript中,可以在多层嵌套作用域中指定具有相同名称的变量。 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 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... 据说这个外部变量被遮盖了...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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