在我们面试中经常遇到这么一道题
var arr = [];
for(var i = 0; i< 5; i++){
arr[i] = function(){
return i;
}
}
arr[0](); // 5
这是因为在执行 for 循环的时候并没有执行函数调用,对于基本类型的调用每次都是值得拷贝,当循环执行结束的时候 i 值已经为 5. 这时,我们就可以使用闭包来做一个局部作用域的调用。
var arr = [];
for(var i = 0; i< 5; i++){
(function(i){
arr[i] = function(){
return i;
}
})(i)
}
arr[0](); // 5
当然也可以选择用 es6 的新的变量声明方式 let 解决上述问题
var arr = [];
for(let i = 0; i< 5; i++){
arr[i] = function(){
return i;
}
}
arr[0](); // 5
定时器每秒打印
var arr = [];
for(var i = 0; i< 5; i++){
setTimeout(() => {
console.log(i)
}, i * 1000);
}
跟预想的结果不一样,打印出来了5个5,而不是1,2,3,4,5.原因相同,因为for 循环已经执行完毕,全局变量 i 已经被赋值为了 5.
闭包解决
var arr = [];
for(var i = 0; i< 5; i++){
(function(i){setTimeout(() => {
console.log(i)
}, i * 1000)})(i);
}
同理可以使用 es6 的新的变量声明方式
var arr = [];
for(let i = 0; i< 5; i++){
setTimeout(() => {
console.log(i)
}, i * 1000);
}