for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
}

结果是:

0 1 2 3 3 3

分析:

1、在实践中,setTimeout 会在其完成当前任何延迟事件的事件处理器的执行,以及完成文档当前状态更新后,告诉浏览器去启用 setTimeout 内注册的函数。

2、setTimeout是异步的。正确的理解setTimeout的方式(注册事件):
                          有两个参数,第一个参数是函数,第二参数是时间值。
                          调用setTimeout时,把函数参数,放到事件队列中。等主程序运行完,再调用。

原题等价于:

 var i = 0;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;

因为setTimeout是注册事件。根据前面的讨论,可以都放在后面。
原题又等价于如下的写法:

 var i = 0;
console.log(i);
i++;
console.log(i);
i++;
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
setTimeout(function() {
console.log(i);
}, 0);
setTimeout(function() {
console.log(i);
}, 0);

参考资料:【http://www.qdfuns.com/notes/17398/e8a1ce8f863e8b5abb530069b388a158/page/3.html#tagsbar】

05-11 23:01