【问题标题】:Understanding JavaScript scopes [duplicate]了解 JavaScript 作用域 [重复]
【发布时间】:2018-04-01 12:37:45
【问题描述】:

我试图了解作用域在 JS 中是如何工作的。你能告诉我如果我对这段代码的理解正确吗:

for(var i = 0; i<5; i++){
 setTimeout(function timeoutHandler() {
   var i = i;
   console.log(i); //undefined
 })
}

console.log 打印undefined 5 次。据我了解,当timeoutHandler 被执行时,它有自己的本地范围和自己的i 变量。那么在timeoutHandler 执行期间,解释器要求i 变量,发现它在本地范围内声明并使用这个声明的变量进行赋值,这是否正确?这解释了为什么它是undefined,但我不确定我是否完全正确。 谢谢

UPD 我不需要这段代码才能正常工作,我只是想了解为什么它在这种情况下会这样

【问题讨论】:

  • var i = i 在 setTimeout 回调处理程序中为ii 创建了一个新范围,在再次将其分配给i 之前尚未定义。因此iundefined
  • 首先var i = i 没有意义。
  • var i = i 等价于var i; i = i;
  • 尝试将i 作为setTimeout 的参数传入
  • @JJJ 这可以解释为什么i 被设置为undefined

标签: javascript scopes


【解决方案1】:

试图通过这个例子来理解它:

for(var i = 0; i<5; i++){
//create a self executing function 
 (function(iValue){
  //in this scope iValue has the i from the loop
  setTimeout(function() {
   console.log(iValue); //will print the correct i
 })
 })(i); //pass i in it's current context to the function
}

或者使用 ES6 更容易: 使用let 而不是var。 由于let 的范围在块内(循环的每次运行都是它自己的块),它不会在setTimeout 内获得另一个值。

for(let i = 0; i<5; i++){
  setTimeout(function() {
   console.log(i); //will print the correct i
 })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    相关资源
    最近更新 更多