let和var在for循环中的不同表现
var声明变量:
var只有函数作用域,没有块级作用域
//函数作用域的表现
function test(){
var i =10;
console.log(i); //
}
test(); //
console.log(i); // i is not defined; //块级作用域对var没有约束
{
var i = 10;
console.log(i); //
}
console.log(i); //
从上面的代码可了解到,块级作用域对var是没有约束作用的。
let声明变量:
let与var不同,let是有块级作用域的。
//块级作用域对let声明的变量有约束
{
let i = 10;
console.log(i); //
}
console.log(i) //ReferenceError
了解了上面的特性再来看看,var和let在for循环的一些不同表现:
//var声明i
function test(){
for(var i=0;i<2;i++){
setTimeout(()=>{
console.log(i);
},0);
}
}
test();
//输出结果:2、2 //let声明i
function test(){
for(var i=0;i<2;i++){
setTimeout(()=>{
console.log(i);
},0);
}
}
test();
//输出结果:0、1
可以看到只是声明方式不一样,输出的结果却有很大的差异。
在此之前还需要了解setTimeout()的执行机制:
setTimeout()是以异步的方式执行的。在执行for循环的时候,并不是执行一次for循环就立刻执行一次setTimeout(),而会让setTimeout()进入另一条线程进行等待,当主线程(这里就是test())执行完后,setTimeout()再依次执行。
在var中执行的时候:
因为var是没有块级作用域的,所以在for循环中声明的i会存在于test()函数作用域中。每一次for循环就会声明一次i,但后面声明的变量会覆盖前面声明的变量。所以当for循环执行完后(此时setTimeout()还未被执行),函数作用域中的i的值就变成2了
而setTimeout()所在的线程中是这样的:
//第一次进栈
setTimeout(()=>{
console.log(i);
}); //第二次进栈
setTimeout(()=>{
console.log(i);
});
这里的i都指向函数作用域中的i。所以输出都为2。
在let中执行的时候:
因为块级作用域的原因,let声明的i都会存在于for块级作用域中,每一次for循环都会生成一个块级作用域。所以setTimeout()在线程中是这样的:
{
let i=0;
setTimeout(()=>{
console.log(i);
});
}
{
let i=1;
setTimeout(()=>{
console.log(i);
});
}
所以会一次输出0,1;
let和var在for循环中的不同表现的更多相关文章
- var与let循环中经典问题
循环1: 下面代码运行结果是输出10 <script> var a =[]; for(var i = 0;i<10;i++){ a[i] = function(){ consol ...
- 对于for循环中使用let或var时,i的作用域范围的记录
在for循环中使用let时,结果如下 for内部定义的i在循环结束后不会覆盖外部的i 在for循环中使用var,且不控制i的作用域时,结果如下 第一个for循环内部定义的i并不会创建,而是直接使用外部 ...
- 三. var let const的理解 以及 立即执行函数中的使用 以及 for循环中的例子
一. 立即执行函数 windows中有个name属性,name='' '' var 如果我们用var name 去声明,那就会改变windows中name的值(因为我们不是在函数作用域中声明的,所以会 ...
- js for 循环中的 变量问题。
今日处理项目中的一个循环,本来就是一个小小的for循环,后来发现该段程序出现了问题,仔细检查代码没有发现其中的错误.无奈只好叫来了老大帮忙.通过在模版中断点调试(该方式只能自己写debugger断点) ...
- js模版引擎handlebars.js实用教程——循环中使用索引
<!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content="text/ ...
- Handlebars.js循环中索引(@index)使用技巧(访问父级索引)
使用Handlebars.js过程中,难免会使用循环,比如构造数据表格.而使用循环,又经常会用到索引,也就是获取当前循环到第几次了,一般会以这个为序号显示在页面上. Handlebars.js中获取循 ...
- jsrender-for循环中访问父属性
jsrender中使用for循环数据时有时需要访问父级数据. 而jsrender在循环中的父级数据存放在隐藏属性parent.parent.data中,使用案例如下 {{:#parent.parent ...
- JQuery在循环中绑定事件的问题详解
JQuery在循环中绑定事件的问题详解 有个页面上需要N个DOM,每个DOM里面的元素ID都要以数字结尾,比如说 ? 1 2 3 <input type="text" nam ...
- bash的循环中无法保存变量
在bash中,如果循环在一个子shell中运行,那么在循环中对循环外面的变量的更改将在循环退出后不可见.像下面的例子: #!/bin/sh python run.py | while read lin ...
随机推荐
- 最初级的ajax程序
该文章实现的ajax功能是实现了在<span>上面添加内容 jsp代码 <html><head><title>Ajax</title>< ...
- h指数|JCR|ORCID|CCC|Research ID|BKCI|
h指数有如下缺点: 年龄大且平庸的学者比杰出的青年学者的h-index大.学科之间h指数的评价标准不同.有时候,审稿人暗示作者引用自己文章. 再此处可找到相关信息: JCR上可以查询到影响因子,以下是 ...
- 德国、日本的制造业为什么不能完全执行SOP?
在过去几十年,德国.日本的制造企业简直就是"以质取胜"的代名词,一些制造业的CEO非常自豪,甚至在公开场合调侃:大家好,我就是"保质保量"本人,也正因如此,德国 ...
- 忘记mysql密码后重置密码
https://jingyan.baidu.com/album/c275f6ba479ca9e33d7567ee.html?picindex=4 找不到mysql的my.ini文件问题: https: ...
- 吴裕雄--天生自然HTML学习笔记:HTML 段落
HTML 可以将文档分割为若干段落. HTML 段落 段落是通过 <p> 标签定义的. 实例 <p>这是一个段落 </p> <p>这是另一个段落< ...
- [洛谷P3369] 普通平衡树 Treap & Splay
这个就是存一下板子...... 题目传送门 Treap的实现应该是比较正经的. 插入删除前驱后继排名什么的都是平衡树的基本操作. #include<cstdio> #include< ...
- Swift 浅谈Struct与Class
讨论Struct与Class之前,我们先来看一个概念:Value Type(值类型),Reference Type(引用类型): 1. 值类型的变量直接包含他们的数据,对于值类型都有他们自己的数据副本 ...
- Kafka配置文件及解释
broker.id=0num.network.threads=9num.io.threads=24socket.send.buffer.bytes=102400listeners=PLAINTEXT: ...
- 安卓权威编程指南-笔记(第24章 Looper Handler 和 HandlerThread)
AsyncTask是执行后台线程的最简单方式,但它不适用于那些重复且长时间运行的任务. 1. Looper Android中,线程拥有一个消息队列(message queue),使用消息队列的线程叫做 ...
- C++走向远洋——63(项目二2、两个成员的类模板)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...