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循环中的不同表现的更多相关文章

  1. var与let循环中经典问题

    循环1: 下面代码运行结果是输出10   <script> var a =[]; for(var i = 0;i<10;i++){ a[i] = function(){ consol ...

  2. 对于for循环中使用let或var时,i的作用域范围的记录

    在for循环中使用let时,结果如下 for内部定义的i在循环结束后不会覆盖外部的i 在for循环中使用var,且不控制i的作用域时,结果如下 第一个for循环内部定义的i并不会创建,而是直接使用外部 ...

  3. 三. var let const的理解 以及 立即执行函数中的使用 以及 for循环中的例子

    一. 立即执行函数 windows中有个name属性,name='' '' var 如果我们用var name 去声明,那就会改变windows中name的值(因为我们不是在函数作用域中声明的,所以会 ...

  4. js for 循环中的 变量问题。

    今日处理项目中的一个循环,本来就是一个小小的for循环,后来发现该段程序出现了问题,仔细检查代码没有发现其中的错误.无奈只好叫来了老大帮忙.通过在模版中断点调试(该方式只能自己写debugger断点) ...

  5. js模版引擎handlebars.js实用教程——循环中使用索引

    <!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content="text/ ...

  6. Handlebars.js循环中索引(@index)使用技巧(访问父级索引)

    使用Handlebars.js过程中,难免会使用循环,比如构造数据表格.而使用循环,又经常会用到索引,也就是获取当前循环到第几次了,一般会以这个为序号显示在页面上. Handlebars.js中获取循 ...

  7. jsrender-for循环中访问父属性

    jsrender中使用for循环数据时有时需要访问父级数据. 而jsrender在循环中的父级数据存放在隐藏属性parent.parent.data中,使用案例如下 {{:#parent.parent ...

  8. JQuery在循环中绑定事件的问题详解

    JQuery在循环中绑定事件的问题详解 有个页面上需要N个DOM,每个DOM里面的元素ID都要以数字结尾,比如说 ? 1 2 3 <input type="text" nam ...

  9. bash的循环中无法保存变量

    在bash中,如果循环在一个子shell中运行,那么在循环中对循环外面的变量的更改将在循环退出后不可见.像下面的例子: #!/bin/sh python run.py | while read lin ...

随机推荐

  1. python的collections模块和functools模块

    collections是Python内建的一个集合模块,提供了许多有用的集合类. namedtuple 我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: >>> ...

  2. Heartbeat(注意iptables和selinux的问题)

    安装 yum –y install heartbeat libnet配置 通过yum安装配置文件目录/etc/ha.d目录下没有配置文件需要从doc目录中复制三个文件.ha.cf.authkeys.h ...

  3. Docker的网络类型

    四种网络类型: None:不为容器配置任何网络功能,--net=noneContainer:与另一个运行中的容器共享Network Namespace,--net=container:containe ...

  4. java 字符串转日期格式

    /** * 字符串转日期格式 * */ public static Date date(String date_str) { try { Calendar zcal = Calendar.getIns ...

  5. 垃圾回收GC

    ​ 每种语言都有自己的垃圾回收机制.接下来我们来讲一下python的垃圾回收机制. 小整数对象池:python对小整数的定义为[-5,257),这些整数对象是提前建立好的,不会被垃圾回收.单个字母也一 ...

  6. Inheritance Learning Note

    好几天没来学习了,昨晚把继承的又整理了一下.想把整理后的东西发到hexo博客上来,却发现命令行又失效了.前几天明明是好的,这几天又没有进行任何操作,网上搜了一下也没有招到合适的解决办法,无奈只能重装了 ...

  7. IDEA 运行junit单元测试方法

    配置Run,增加Junit 最终配置如下:

  8. C++走向远洋——47(第十二周、运算符重载基础程序、阅读)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  9. CSS过渡、动画及变形的基本属性与运用

    [逆战班] 动画可以让一个元素具有动态的效果,这个过程是使元素从一种样式变成另一个样式的过程.我们可以通过设置关键帧的方法来控制动画在某个时间节点的运动方式.通常设置多个节点来实现复杂的动画效果.0% ...

  10. 7-29 jmu-python-不同进制数 (10 分)

    输入一个十进制整数,输出其对应的八进制数和十六进制数.要求采用print函数的格式控制进行输出,八进制数要加前缀0o,十六进制数要加前缀0x. 输入格式: 输入一个十进制整数,例如:10 输出格式: ...