let、 var、 setTimeout,一点思考。javascript
for(var i = 0; i < 10; i++){ setTimeout(function(){ console.log(i); },100); }
结果是很显而易见的,10次都是10,在面试前端的闭包知识时候很常见。
用上let以后,前端
for(let i = 0; i < 10; i++){ setTimeout(function(){ console.log(i); },100); }
结果是:
0、一、二、三、四、五、六、七、八、9java
为何var和let声明的i,获得不一样的结果?面试
var声明的i,做用域不单单在for循环内,还在for循环的外部。闭包
当setTimeout执行的时候,for循环已经完成,i此时的值是10,咱们稍微调整一下代码:函数
for(var i = 0; i < 10; i++){ setTimeout(function(){ consoleLog(); },100); } function consoleLog(){ console.log(i); }
结果是10次10。ui
for(var i = 0; i < 10; i++)
和spa
var i; for(i = 0; i < 10; i++)
等价。code
可是在let声明的时候则不同,ip
for(let i = 0; i < 10; i++)
和
let i; for(i = 0; i < 10; i++)
是不等价的,由于let声明只在代码块中有效。
可是,若是仅仅这样,咱们或许很容易理解
for(var i = 0; i < 10; i++){ setTimeout(function(){ console.log(i); },100); }
获得10次10,然而为何
for(let i = 0; i < 10; i++){ setTimeout(function(){ console.log(i); },100); }
获得0-9?
在setTimeout的时候,匿名函数function(){console.log(i);}会被声明建立,当匿名函数执行的时候,会查找当前运行环境的 i 的值。
var声明的 i ,运行环境的 i 的值为10,可是let声明的 i,运行环境中 i 的值是每个循环建立匿名函数时候的 i。
因此获得了0-9的值。
let替换var,能够很好的解决闭包的问题。