当函数可以记住并访问该函数所在的词法作用域时,就产生了闭包,即函数在当前的词法作用域之外执行。当函数跳出当前的词法作用域之外,但是该函数有对它所在的词法作用域的引用,这样采用标记--清除算法的Javascript垃圾回收机制,就能够从根部出发找到该词法作用域。因此,该词法作用域不会被垃圾回收。这样,该块词法作用域可以和全局变量一样存储在内存中,直到没有应用只想该块词法作用域(也就是从根出发无法找到该块词法作用域)。
for (var i =1 ; i<=5; i++)
{
setTimeout(function Timer(){
console.log(i)}, i*1000);
}
上面的例子也是闭包的一种,即函数在当前的词法作用域之外被调用。该函数会以每秒一次的频率输出5次6,因为当Timer()函数执行时,此时的i==6,所以循环调用的setTimeout()函数都访问同一个全局变量i。
如何能够让该函数以每秒一次的频率输出1~5呢?
这时就要为每次调用的setTimeout()函数创建一个闭包作用域:
for(var i =1 ;i <=5 ;i++)
{
(function (j){
setTimeout(function Timer(){
console.log(i)}, i*1000);})(i);
}