同步发布于:https://mingjiezhang.github.io/(转载请说明此出处)。

ES6中加入了let,也让JavaScript拥有了块级作用域。

没有块级作用域的JavaScript

在ES5及其之前的版本里,作用域只有全局作用域和函数作用域两种,而不像其他许多语言一样还拥有块级作用域。没有块级作用域的JavaScript在使用的过程中出现了许多意想不到的具体问题,比如下面这段代码的demo:

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

如果是学过C++或者其他有块级作用域的人,可能类比觉得上述代码会输出3,不过事实上该代码输出的是10。

因为ES5及之前是没有块级作用域的,i所处的仍是全局作用域而不是块级作用域。因此,循环过程中数组arr的每个数组项所引用的函数中的变量i都是引用全局作用域中的i,因此arr3中i为for循环结束时的i的值10。

对于该问题,有很多方法解决。比如可以将for循环体的代码放入一个立即执行函数中,相当于创建一个新的作用域,将i当做实参传入里及执行函数,本质上是创造了一个模拟的块级作用域,当然也可以认为为内部的函数创建一个闭包(闭包的本质和作用域链息息相关)。

let的出现

现在我们再写之前的那段代码是,有了更加简洁的方法,使用ES6的let。

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

let的出现使得JavaScript终于拥有了块级作用域。因为ES6要考虑之前版本的兼容,所以是通过声明let来使用块级作用域。

当我们在一个代码块中使用let来声明变量,通过let声明的变量只在当前块作用域中有效。

{
let a = 1;
var b = 2;
}
console.log(a); //ReferenceError
console.log(b); //2

如上,let的声明方式让let所在的块成为块级作用域,同时let声明的变量无法在全局作用域中访问到,但是var变量依旧可以在全局作用域访问到。

无变量提升

let中不存在变量提升的现象。变量在使用之前必须被声明。

因此,这个定义也导致了暂时性死区的现象。

var c = 'test';
if (true) {
c = 'new'; //ReferenceError
let c;
console.log(c);
}

如上在块级块级作用域中重新声明全局作用域中的c时,这时,编译器会屏蔽全局作用域中的c,在该块级作用域中只能使用新声明的c。但由于块级作用域中let声明的变量无作用域提升现象,因此无法在声明c之前使用c(包括赋值c),出现暂时性死区的现象。

块级作用域

let的出现让JavaScript可以充分利用块级作用域的特性。我们可以在不同的块级作用域中使用同名变量。

if (true) {
let a = 1;
if(true){
let a = 2;
console.log(a); //2
}
console.log(a); //1
}

由于块级作用域出现,我们可以实现上述变量隔离的效果。

总结

let在不影响var使用的情况下,开创了JavaScript的块级作用域,未来想必let也会大量取代var的使用。

欢迎指正交流。未经允许,请勿转载。

ECMAScript 6学习笔记(二):let和块级作用域的更多相关文章

  1. ES6学习笔记(1)- 块级作用域

    1. var声明变量和变量提升(Hoisting)机制的问题 在JS中通过var关键字声明的变量,无论在函数作用域中亦或是全局作用域中,都会被当成当前作用域顶部的变量,和就是所谓的提升机制(Hoist ...

  2. CSS学习笔记——盒模型,块级元素和行内元素的区别和特性

    今天本来打算根据自己的计划进行前端自动化的学习的,无奈早上接到一个任务需求需要新增一个页面.自从因为工作需要转前端之后,自己的主要注意力几 乎都放在JavaScript上面了,对CSS和HTML这方面 ...

  3. ECMAScript 6 学习笔记(二)

    ECMAScript 6 let和const命令 let命令 基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a ...

  4. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  5. python3.4学习笔记(二) 类型判断,异常处理,终止程序

    python3.4学习笔记(二) 类型判断,异常处理,终止程序,实例代码: #idle中按F5可以运行代码 #引入外部模块 import xxx #random模块,randint(开始数,结束数) ...

  6. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  7. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  8. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  9. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

随机推荐

  1. 使用 AFNetworking 进行 XML 和 JSON 数据请求

    (1)XML 数据请求 使用 AFNetworking 中的 AFHTTPRequestOperation 和 AFXMLParserResponseSerializer,另外结合第三方框架 XMLD ...

  2. jquery自定义类似$.ajax()的方法

    热腾腾的代码: <script type="text/javascript"> $.extend({ testgogo: function (options) { va ...

  3. WCF的传输安全(读书笔记)

    Wcf的传输安全主要涉及认证.消息的一致性和机密性.Wcf采用两种不同的机制来解决这三个涉及传输安全的问题,即Transport安全模式和Message安全模式. Transport安全模式利用基于传 ...

  4. [原]零基础学习视频解码之seek

    现在,我们要添加一些功能,当你看不能倒带的电影,是不是很烦? 那么函数av_seek_frame功能看起来是多么赏心悦目. 我们将让左,右箭头来回走在影片中通过一个小的向上和向下箭头很多,其中“三多一 ...

  5. Failure is not fatal, but failure to change might be.

    Failure is not fatal, but failure to change might be. 失败不是致命的,但无法改变却可能是致命的.

  6. HANA Studio打开系统显示Secure storage is locked

    之前一直用着好好的,今天打开HANA Studio突然发现一个系统都不在了: 提示:‘Secure storage is locked’ 我点旁边的Unlocked没有任何反应,右键也没有功能了.如下 ...

  7. Fenix – 基于 Node.js 的桌面静态 Web 服务器

    Fenix 是一个提供给开发人员使用的简单的桌面静态 Web 服务器,基于 Node.js 开发.您可以同时在上面运行任意数量的项目,特别适合前端开发人员使用. 您可以通过免费的 Node.js 控制 ...

  8. iOS-沙盒路径总结、文件管理NSFileManager总结

    // //  ViewController.m //  沙盒操作 // //  Created by mncong on 15/11/26. //  Copyright © 2015年 mancong ...

  9. Android 简单计算器源码....

    PS:今天算是闲着没事做了一个小型的计算器...顺便熟悉一下Android的布局,组件,以及时间监听的方法...就当是做了一个小小的练习吧...     顺便去对比了一下别人写的代码...有的使用到了 ...

  10. ActiveMQ学习(三)——MQ的通讯模式

    1) 点对点通讯:点对点方式是最为传统和常见的通讯方式,它支持一对一.一对多.多对多.多对一等多种配置方式,支持树状.网状等多种拓扑结构. 2) 多点广播:MQ适用于不同类型的应用.其中重要的,也是正 ...