Javascript函数范围[Javascript Essentials]

Ste*_*n-v 2 javascript arrays for-loop function anonymous-function

我正在看Travis Tidwell的Javascript Essentials,他解释了这段代码:

(function() {
    var messages = ['hello', 'there'];

    for (var i in messages) {
        setTimeout(function() {
            console.log(messages[i]);
        }, 10); 
    };
})();
Run Code Online (Sandbox Code Playgroud)

它在控制台中回响了'那里'两次,但我仍然不明白为什么.有人可以一步一步地浏览这段javascript吗?

Que*_*tin 5

每次代码绕过循环时,它都会设置一个事件处理程序,以便在经过10ms后,它会记录值messages[i].

在超过任何这些超时的10ms之前,已经将值i(通过for循环)更改为1(因为这是数组中的最后一个属性名称).

然后输出第一个超时,然后输出messages[1]第二个超时输出messages[1].


  1. 创建并存储数组 messages
  2. i设置为0并设置超时
  3. i设置为1并设置超时
  4. 第一次超时功能运行,i仍然是1
  5. 第二次超时功能运行,i仍然是1

  • @johnnyRose浏览器施加的最小超时值通常超过10毫秒. (3认同)
  • 因为(a)强制执行最小超时并且(b)JavaScript是单线程的,所以事件循环在运行另一个函数时不会查找要处理的事件. (3认同)
  • "但真的很奇怪,当设置超时时,它不存储i [0]计数" - 不,它不是.这是JavaScript的基本功能.创建函数不会立即创建每个变量的本地范围副本并冻结其值.在使用它之前,该功能甚至不会查看`i`. (2认同)