一个经典for循环例子:
for(var i=0;i<3;i++){
setTimeout(function(){
console.log(i);
})
}
以上代码输出结果是:3个3
原因是:setTimeout是异步操作不会马上执行,eventloop会等主线机制完成后执行,而for是同步执行,因此执行settimeout的时候for循环已经执行完了,结果打印的值为3个3
如果需要使其打印结果为0,1,2,可使用闭包的方法
for(var i=0;i<3;i++){
(function(j){ //外部函数
setTimeout(function(){ //内部函数
console.log(j);
})
})(i)
}
闭包的特性:闭包是有一个外部函数和一个内部函数,内部函数settimeout调用外部函数function的变量,保证外部变量的变量不被释放,执行for的时候瞬间i为0,1,2,虽然很快但这个状态始终存在,闭包让i的每次状态不被释放,因此结果执行打印出0,1,2
更简单的方式是用ES6声明变量的方法let
for(let i=0;i<3;i++){
setTimeout(function(){
console.log(i);
})
}
遍历 i 是通过 let 关键字声明的:通过 let 和 const 关键字声明的变量是拥有块级作用域(指的是任何在 {} 中的内容)。在每次的遍历过程中,i 都有一个新值,并且每个值都在循环内的作用域中,使其结果依次输出0,1,2