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保存每次的值;