回顾下闭包形成的条件:
- 在函数内部创建新的函数
- 内部函数访问了父函数的变量
setTimeout
中定义的操作,会放在一个FIFO队列中,且需要等待到函数调用栈清空之后才开始依次执行,这些操作进入队列的顺序,则由设定的延迟时间来决定。
面试题
利用闭包,修改下面的代码,让循环输出的结果依次为1, 2, 3, 4, 51
2
3
4
5
6for (var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log(i);
}, i*1000 );
}
解法1
利用闭包的特性,通过包裹一层自执行函数为闭包的形成提供条件1
2
3
4
5
6
7for (var i=1; i<=5; i++) {
(function(i) {
setTimeout( function timer() {
console.log(i);
}, i*1000 );
})(i)
}
or1
2
3
4
5
6
7for (var i=1; i<=5; i++) {
setTimeout( (function(i) {
return function() {
console.log(i);
}
})(i), i*1000 );
}
解法2
利用setTimeout
第三个参数1
2
3
4
5for (var i=1; i<=5; i++) {
setTimeout(function (i) {
console.log(i);
}, i*1000,i );
}
解法3
利用bind
方法1
2
3
4
5for (var i=1; i<=5; i++) {
setTimeout(function (i) {
console.log(i);
}.bind(null,i), i*1000 );
}
解法4
利用ES6中的let
1
2
3
4
5for (let i=1; i<=5; i++) {
setTimeout( function timer() {
console.log(i);
}, i*1000 );
}