javascript 闭包与函数变量作用域

浏览器事件循环工作原理

浏览器有一个事件循环用于检查事件队列,处理延时的事件、UI事件(例如:点击,滚动等),ajax回调,以及提供给setTimeout()和setInterval()的回调,都会依次被事件循环处理。

因此,当调用setTimeout()函数时,即使延迟的时间被设置为0,提供的回调也会被排队

回调会呆在队列中,直到指定的时间用完后,引擎开始执行动作(如果它当前不执行其他动作)

因此,即使setTimeout()回调被延迟0ms,它仍然会被排队,并且直到函数中其他非延迟的语句被执行完了之后,才会执行

浅谈从一道面试测试题谈谈对Nodejs编程的理解

原题链接:

https://cnodejs.org/topic/55145859e26684ed7ff21bd3

 1 var value1 = 0, value2 = 0, value3 = 0;
 2 for ( var i = 1; i <= 3; i++) {
 3   var i2 = i;
 4   (function() {
 5     var i3 = i;
 6     setTimeout(function() {
 7       value1 += i;
 8       value2 += i2;
 9       value3 += i3;
10     }, 1);
11   })();
12 }
13 setTimeout(function() {
14   console.log(value1, value2, value3);
15 }, 100);

根据上面  浏览器事件循环工作原理  可知:

  • setTimeout()函数会被放在事件队列中,在其他非延迟语句执行完之后,才运行。

解析:

函数变量作用域

value1 分析:

在setTimeout()函数里的匿名函数中

1 function() {
2   value1 += i;
3   value2 += i2;
4   value3 += i3;
5 }

使用了i变量,但,i变量在setTimeout()函数里的匿名函数中并没有被定义,于是向外查找,在setTimeout()函数里也没有被定义,于是再向外查找....直到找到for循环里的;但此时,for循环已经执行完毕,i的值是4;

所以 value1 的值,是 4+4+4 =12;

value2 分析:

同理可知: 当setTimeout()函数执行的时候,for循环已执行完毕。 变量i2的值为最后一次进入循环的i的值。即为: 3,3,3 (因为当i的值是4的时候,就不满足进入循环的条件了(i <=3)) ,则: value2的值为3+3+3 = 9

对于value3的值,则是 1+2+3 = 6;

value3 分析:

1(function() {
2  var i3 = i;
3  setTimeout(function() {
4    value1 += i;
5    value2 += i2;
6    value3 += i3;
7  }, 1);
8})();

使用一个立即执行的函数创建一层闭包,这时候把i作为一个变量的值赋值给了i3,函数立即执行,i3保存每次的值;

原文地址:https://www.cnblogs.com/sxshijingjing/p/4832149.html