正常情况
for (var i=0;i<10;i++){
console.log(i);
}
image.png
在看看容易让人产生疑惑的情况
var a = [];
for (var i = 0; i < 10; i++) {
// 作用域a
a[i] = function () {
// 作用域b
console.log(i);
};
}
a[6](); // 10
image.png
没有像我们预想的出现6而是10。原因:for循环中头部使用var 定义变量i 时,它和循环体中的i 的作用域不是同级作用域,因此当for循环执行完毕后,并不会给每个循环都储存相对应的i的值。(注意,这种情况只有在循环体执行完时才会发生,直接在循环体中写同步执行的数据,是可以拿到对应的i的值的。也就是这种情况一般发生在循环体中存在执行函数,这个函数的触发执行时机是在for循环执行完毕后)
解决办法
1. 自执行函数解决法(针对老浏览器)
var a = [];
for (var i = 0; i < 10; i++) {
(function(j){
a[j] = function () {
// 作用域b
console.log(j);
};
})(i)
}
a[6]();//6
image.png
解决的思想就是 既然每轮循环的值无法储存,那我们就在每轮循环执行时,执行一个自执行的匿名函数,并且把此轮的i当做参数传递进去。这样就创建了一个新的作用域,新的作用域中会我们使用变量j来储存i的值。每轮循环都会创建自执行函数,因此j作用域是互相独立的.
2. let(针对 手机端,node 等支持es6的环境)
var a = [];
for (let i = 0; i < 10; i++) {
// 作用域a
a[i] = function () {
// 作用域b
console.log(i);
};
}
a[6](); // 6
image.png
简单粗暴,es6的let就是为支持块级作用域而生,因此。。。。。
网友评论