JS中的for循环易错
第一种for循环,常用且易错,var 定义的变量i 属于全局变量,执行setTimeout之前,i已被修改为了5
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 1000)
}
//5
首先让我们重新理解下for循环的本质,即满足循环条件的情况下多次执行相同的循环体,然后我们将上面的循环拆解为以下的方式,再来看看
变量 i 是全局变量 , 大括号内的i,并没有作用域,可以被修改影响,js的执行机制,setTimeout执行时,i 早已被修改为 5了,所以,会打印5次
var i = 0;
{
i = 0;
setTimeout(() => {
console.log(i);
}, 1000)
}
{
i = 1;
setTimeout(() => {
console.log(i);
}, 1000)
}
{
i = 2;
setTimeout(() => {
console.log(i);
}, 1000)
}
{
i = 3;
setTimeout(() => {
console.log(i);
}, 1000)
}
{
i = 4;
setTimeout(() => {
console.log(i);
}, 1000)
}
i = 5;
第二种for循环,利用闭包的原理,setTimeout函数在立即执行函数内部,i作为参数传到了立即执行函数里面,函数是有作用域的
for (var i = 0; i < 5; i++) {
(function (i) {
return setTimeout(() => {
console.log(i);
}, 1000)
})(i)
}
//0
//1
//2
//3
//4
我们以相同的方式拆解第二种for循环的循环体,循环体是一个立即执行函数(IIFE), 函数有作用域 ,且在执行的时候就会把值传进函数内部
var i = 0;
{
i = 0;
(function (i) {
return setTimeout(() => {
console.log(i);
}, 1000)
})(i) //i=0
}
{
i = 1;
(function (i) {
return setTimeout(() => {
console.log(i);
}, 1000)
})(i) //i=1
}
{
i = 2;
(function (i) {
return setTimeout(() => {
console.log(i);
}, 1000)
})(i) //i=2
}
{
i = 3;
(function (i) {
return setTimeout(() => {
console.log(i);
}, 1000)
})(i) //i=3
}
{
i = 4;
(function (i) {
return setTimeout(() => {
console.log(i);
}, 1000)
})(i) //i=4
}
i = 5;
第三种for循环,使用了ES6 的语法,let 关键字定义的变量是有作用域的
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 1000)
}
//0
//1
//2
//3
//4