昨天夜里,在重新理解使用闭包解决for
循环中函数正确访问变量的问题时,发现了了这个知识盲区,请大佬讲解一下。
问题如下:
for ( var i = 0; i < 5; ++i ) {
setTimeout( function() { console.log( i ) }, 100 );
}复制代码
由于JavaScript不存在块级作用域,这个循环执行五次后,setTimeout
函数中的回调会打印出:
5 5 5 5 5复制代码
在不使用ES6中的块级绑定声明,let
,const
(会因为声明变量只读问题报错)的情况下,一般会通过闭包这一特性解决变量 i
的正确访问问题。如下:
for ( var i = 0; i < 5; ++i ) {
(function( j ) {
var j = i;
setTimeout( function() { console.log( j ) }, 100 );
})( i );
}复制代码
结果如下:
0 1 2 3 4复制代码
如果我们不使用IIFE
函数,而使用具名函数:
for ( var i = 0; i < 5; ++i ) {
function closure( i ) {
var j = i;
setTimeout( function() { console.log( j ) }, 100 );
}
closure( i );
} 复制代码
同样得到如下结果:
0 1 2 3 4复制代码
在每次循环中都会重写closure
函数,但是当100毫秒后,事件队列中的打印函数执行时,仍然可以访问到与其对应closure
函数的作用域中。这是否说明函数重写带来的覆盖问题,并不会覆盖之前函数的作用域。希望大佬能够讲解一下!