|
题目如下:
<script>
for(var i=0;i<5;i++){
setTimeout(function(){
console.log(i)
},1000)
}
console.log(i);
</script>上面代码的输出结果(请先思考 )?
(请先思考 )? (请先思考 )? (请先思考 )? (请先思考 )? 结果为:先执行循环外的i , 输出结果5 在输出setTimeOut里的i , 输出结果为5 个5 现在,请思考 ,如何可以输出5 , 0,1,2,3,4 (请先思考 )? (请先思考 )? (请先思考 )? (请先思考 )? 这时,大家想到了,可以用let , 代码如下: <script>
for(let i=0;i<5;i++){
setTimeout(function(){
console.log(i)
},1000)
}
console.log(i);
</script>for里的变量使用let , 根据let 的作用域, setTimeout的i ,可以分别输出0,1,2,3,4
但是,for外的i , 却不能访问到i , 而我们是想让它输出结果: 5 如何实现 ? (请先思考 )? (请先思考 )? (请先思考 )? (请先思考 )? 方法一 (直接使用简单的方法赋值,但是不够高级): <script>
for(var i=0;i<5;i++){
let j = i;
setTimeout(function(){
console.log(j)
},1000)
}
console.log(i);
</script> 解析:
var声明的变量全局范围内都有效。所以每次循环,新的i值都会覆盖旧值 let声明的仅在块级作用域内有效,最后输出6 let不会发生变量提升的现象,所以一定要在定义后使用,否则报错。 暂时性死区:只要块级作用域内存在let命令,它所声明的变量就绑定这个区域,不再受外部影响。 详情参考:https://www.cnblogs.com/chengyunshen/p/7191571.html 方法二 (使用闭包,其实还是赋值,只是实参赋给形参) <script>
for(var i=0;i<5;i++){
(function (j){
setTimeout(function(){
console.log(j)
},1000)
})(i);
}
console.log(i);
</script>
解析: 闭包实现,其实主要也是因为函数,会创建自己对应的作用域,不会被改变 原创文章,转载请注明出处 http://bugshouji.com/shareweb/t454 |
|