for循环:闭包
for (var i=1; i<=5; i++) { setTimeout( function timer() { console.log( i ); }, i*1000 ); } /* 控制台打印: 6 6 6 6 6 6 */
可是咱们但愿的结果是:函数
1 2 3 4 5
缘由是,延迟函数的回调会在循环结束时才执行。当定时器运行时即便每一个迭代中执行的是setTimeout(.., 0),全部的回调函数依然是在循环结束后才会被执行,所以会每次输出一个6 出来。code
咱们改写一下:作用域
for (var i=1; i<=5; i++) { (function() { setTimeout( function timer() { console.log( i ); }, i*1000 ); })(); } /* 6 6 6 6 6 */
缘由:若是做用域是空的,那么仅仅将它们进行封闭是不够的。它须要包含一点实质内容才能为咱们所用。它须要有本身的变量,用来在每一个迭代中储存i 的值:回调函数
继续改写:io
for (var i=1; i<=5; i++) { (function() { var j = i;//保存外部变量 setTimeout( function timer() { console.log( j ); }, j*1000 ); })(); } /* 1 2 3 4 5 */ //代码改进:(将i当参数传进去) for (var i=1; i<=5; i++) { (function(j) { setTimeout( function timer() { console.log( j ); }, j*1000 ); })( i ); }
总结console
当函数能够记住并访问所在的词法做用域,即便函数是在当前词法做用域以外执行,这时 就产生了闭包。