前言
let与var最大的区别就是var会变量提升、var会被覆盖、var变量没有块级作用域,而let都将弥补这些bug。
传统语言都不会有‘变量提升、重复声明被覆盖、变量没有块级作用’这些问题,这是js的bug(js说这锅我不背,这是es6出的标准,我只是实现它)
js里边只有全局作用域和函数作用域
而传统编程语言是存在块级作用域的,所谓块级,就是用{xxx}里边的,比如语句、函数、代码块{ }。
但是js只有函数里的变量享有块级作用域的待遇,其他均没有,这是个bug。后来es6除了个let弥补了这些bug。

最经典的代码,使用var

 var arr=[];
for(var i=0; i<3; i++){
arr[i]=function () {
console.log(i);
}
}
arr[1]() //打印3

原因解析,执行流程:
因为js不存在块级作用的概念,所以i其实是存在于全局作用域的。

当i=0
arr[0]=function(){console.log(0)}

当i=1
---arr[0]=function(){console.log(1)}---
arr[1]=function(){console.log(1)}

当i=2
---arr[0]=function(){console.log(2)}---
---arr[1]=function(){console.log(2)}---
arr[2]=function(){console.log(2)}

当循环完毕后
i<3然后i++,所以for循环结束后,i最终结果为3。!!!!!!注意i已经为6了
arr[0]=function(){console.log(3)}
arr[1]=function(){console.log(3)}
arr[2]=function(){console.log(3)}
arr[3]=function(){console.log(3)}

每次循环都会导致本轮循环的i覆盖掉全局的i,所以当循环完毕后在执行 arr[无论是几](),结果都是3

---xxx---表示该素组元素对应的函数里的i值将会被本轮循环里的i覆盖

如果使用let,则不会发生上边的情况

var arr=[];
for(let i=0; i<3; i++){
arr[i]=function () {
console.log(i);
}
}
arr[1]() //打印1

原因解析,执行流程:
这是因为用let的变量i,会形成块级作用域,i不在是全局的了。每次循环都不会导致本轮循环的i覆盖掉全局的i,各是个的。不会被覆盖。
那么循环结束后,执行某一个arr[?]( )它都能够记住并打印出当时的那轮循环的那次i的值呢?
阮一峰说:这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。再简单点,就是JavaScript 引擎内部记住了

言外话
闭包,就是函数嵌套函数,因为函数存在作用域,所以大家都喜欢用闭包来模拟块级作用域
let没出来之前,这确实有必要,let出来之后,闭包的意义就不是太大了

let 与 var的更多相关文章

  1. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  2. var和dynamic的区别

    1.var 1.均是声明动态类型的变量. 2.在编译阶段已经确定类型,在初始化的时候必须提供初始化的值. 3.无法作为方法参数类型,也无法作为返回值类型. 2.dynamic 1.均是声明动态类型的变 ...

  3. Kotlin中变量不同于Java: var 对val(KAD 02)

    原文标题:Variables in Kotlin, differences with Java. var vs val (KAD 02) 作者:Antonio Leiva 时间:Nov 28, 201 ...

  4. 在开发中到底要不要用var?

    var是.net的一个语法糖,在Resharper中推荐都使用这个关键字,平常我也是经常用:但是在跟其他程序员推广使用时,他的一些考虑引发了我的深思,到底该不该使用这个关键字呢? 我使用的理由 我使用 ...

  5. 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。

    最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...

  6. javaScript中的小细节-局部作用域中的var

    javaScript中var是很神奇的,在局部作用域中,var a = b = c = 1;是不一样的,a为使用var声明的变量,而b和c则是全局下的,此类变量被称为隐式全局变量:var a = 1; ...

  7. ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock

    ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock 通过终端安装程序sudo apt-get install xxx时出错:E: Could not ...

  8. /var/log/messages

    messages 该日志文件是许多进程日志文件的汇总,从该文件可以看出任何入侵企图或成功的入侵,包括整体系统信息,是系统最核心的日志.它包含了系统启动时的引导消息,以及系统运行时的其他状态消息.IO ...

  9. Ubuntu14.04无法在var/www内新建文档

    /var/www文件夹的所有者属于www-data用户组. 要想用你自己的帐号在/var/www里面创建文件和文件夹,最好的办法是把自己的帐号纳入到www-data用户组中. 命令:sudo user ...

  10. Mac 下locate命令使用问题WARNING: The locate database (/var/db/locate.database) does not exist.

    想在Mac下使用locate时,提醒数据库没创建: WARNING: The locate database (/var/db/locate.database) does not exist. To ...

随机推荐

  1. ThinkPHP跳转与重定向的区别

    跳转: 浏览器认为: 当前URL请求成功, 重新请求新的URL. 浏览器会 记录当前的URL 和 新的URL 在请求历史记录中. 回退, 是可以回退到, 当前的URL上的. (无论 success, ...

  2. jquery合并表格中相同文本的相邻单元格

    <!DOCTYPE HTML> <html> <head>   <title>Example</title>   <meta char ...

  3. Android动态禁用或开启屏幕旋转工具

    package com.gwtsz.gts2.util; import android.content.Context; import android.provider.Settings; impor ...

  4. springboot整合mybatis之用外置服务器启动项目(二)

    在上一篇中我们是用的springboot自带的tomcat服务器,接下来想试一下 将springboot当做一个web项目 放在eclipse中用tomcat来启动. 首先在pom.xml中加上,移除 ...

  5. Android之布局属性归纳

    第一类:属性值为true或falseandroid:layout_centerHrizontal 水平居中android:layout_centerVertical 垂直居中android:layou ...

  6. ORA-28000: the account is locked

    1.用system账号登录 2.执行一下sql: ALTER USER username ACCOUNT UNLOCK; 此处username 可能为scott或者你要解锁的用户名. ........ ...

  7. 面试之二:Redis是单线程还是多线程?以及处理模型。

      Redis是单线程还是多线程?以及处理模型. 线程:单线程 处理模型:参考书<Redis 设计与实现>P151-152 ![](https://ws1.sinaimg.cn/large ...

  8. python--base64

    import base64import os # base64,参数为文件路径名def file_base64(filepath): if os.path.isfile(filepath): with ...

  9. C#全角半角转换输出解决方法

    Microsoft.VisualBasic 命名空间 Strings 模块 StrConv 函数就具有大写/小写.全角/半角.中文简体/繁体等转换功能,字符串转换应该说是VB.NET的强项,是这样的: ...

  10. WebSocket之获取HttpSession

    WebSocket之获取HttpSession 由于WebSocket与Http协议的不同,故在使用常用的HttpSession方面就存在了一些问题.通过google翻阅到了在onOpen方法下使用H ...