本系列是在平时阅读、学习、实际项目中有关于es6中的新特性、用发的简单总结,目的是记录以备日后温习;本系列预计包含let/const、箭头函数、解构、常用新增方法、Symbol、Set&Map、Proxy、reflect、Class、Module、Iterator、Promise、Generator、async/await

let/const为我们带来了什么?

let

  1. 约束变量提升

    (function foo() {console.log(a);let a = 1;})();// Uncaught ReferenceError: a is not defined

    总结下来就是一句: 在变量使用之前,必须先要声明,变量声明永远在使用之前。

  2. 带来了块级作用域
    // es5(function(){if(false) {var temp = 1;}console.log(temp); // undefined
        })();// es6(function(){if(false) {let temp = 1;}console.log(temp); // Uncaught ReferenceError: temp is not defined})();

    从代码中我们可以很清晰看到es6的let的块级作用域,那么块级作用域有什么应用呢?举个例子:

    var fnArr = [];for(var i = 0; i < 5; i++) {fnArr.push(function() {console.log(i);});}fnArr[0](); // 5fnArr[1](); // 5fnArr[2](); // 5fnArr[3](); // 5fnArr[4](); // 5console.log(i); // 5

    如果没有仔细分析,执行的结果是不是有些出乎意料呢? 是的,我们本意在for循环内部使用的变量i被泄露成了全局变量,而且在for循环的每一次循环,变量i并没有被重新声明,实际上数组fnArr中保存的每一个函数中引用的都是同一个变量i,所以才导致了现在的结果,那怎么让代码按照我们最初的想法运行呢?来看es5中常用的解法

    var fnArr1 = [];for(var i = 0; i < 5; i++) {(function(j) {fnArr1.push(function() {console.log(j);});})(i)}fnArr1[0](); // 0fnArr1[1](); // 1fnArr1[2](); // 2fnArr1[3](); // 3fnArr1[4](); // 4console.log(i); // 5

    看起来是解决了,这里实际上用到了闭包的方法,fnArr1中每一项函数引用的j都是当前循环时i的一个副本,这样就解决了前面的问题,但是还有一个问题: 变量i仍然隐式得泄露到了全局

    var fnArr1 = [];for(let i = 0; i < 5; i++) {fnArr1.push(function() {console.log(i);});}fnArr1[0](); // 0fnArr1[1](); // 1fnArr1[2](); // 2fnArr1[3](); // 3fnArr1[4](); // 4console.log(i); // Uncaught ReferenceError: i is not defined

    OK,问题解决了,仅仅是将’var‘替换成了let,这就是let带来的便利。

  3. 产生暂时性死区&禁止重复声明
    // 什么是禁止重复声明呢? 先不给书面解释,来看一个es5中经常的写法
    (function() {var temp = 1;var temp = 2;var temp = function() {return 1;};})();

    上面这段代码执行没有任何问题,最终temp被赋值为一个函数

    (function() {let temp = 1;var temp = 2; // Uncaught SyntaxError: Identifier 'temp' has already been declaredvar temp = function() {return 1;};})();

    在第三行时就抛出了一个错误:temp已经被声明,是的,let声明过的变量,是不允许再次被声明的,再给几个例子巩固一下:

    (function() {var temp = 2;var temp = function() {return 1;};let temp = 1; // Uncaught SyntaxError: Identifier 'temp' has already been declared
        })();(function() {if(true) {let temp = 1;var temp = 2; // Uncaught SyntaxError: Identifier 'temp' has already been declared
            }})();(function() {if(true) {let temp = 1;function temp() { // Uncaught SyntaxError: Identifier 'temp' has already been declaredreturn 1;}}})();

    看出来了吗?只要是在let声明所在的作用域,就不允许再次声明同名变量(包括函数声明)

    var foo = 1;if(true) {foo = 2; // Uncaught ReferenceError: foo is not defined
            let foo;}

    看到let的’霸道‘了吧?只要在let所在的作用域,同名的变量就会被let占有,不允许重复声明,同时也要遵守let的规则

  4. 全局变量不再作为window对象的属性
    var foo = 1;(function() {bar = 2;})();window.foo; // 1window.bar; // 2

    是的,es5中,全局变量(包括意外泄露的)都将自动被添加为window对象的属性

    let foo = 1;window.foo; // undefined

    一切尽在不言中。。。

const

  1. let所拥有的特性,const都有,同时const还有一条:const声明的变量必须进行初始化,并且不能再被重新赋值

    const temp = 1;temp = 2; // Uncaught TypeError: Assignment to constant variable.

    注意是不能被重新赋值,这样是比较准确的,其实const声明的变量是可以被修改的,当const声明的变量被初始化为复杂数据类型时,const声明的变量就是可变的,至于为什么,自己理解喽(变量标识符中保存的只是复杂数据类型内存地址而已。。。)

    const temp = {};temp.foo = 'aa'; // 这里没问题temp = {foo: 'aa'}; // 这里就会抛出异常

for循环中的变量声明

前面在记录let块级作用域的时候,我们使用了一个for循环的例子,这里我们不妨试着解析一下for循环的执行过程

var fnArr = [];for(var i = 0; i < 3; i++) {fnArr.push(function() {console.log(i);});}// 伪代码var fnArr;fnArr = [];{var i;i = 0;if(i < 3) {fnArr.push(function() {console.log(i);})}i++;if(i < 3) {fnArr.push(function() {console.log(i);});}i++;...}

这里可惜清晰得看到所有的i都是一个i。。。那使用了let以后呢?

var fnArr = [];for(let i = 0; i < 3; i++) {fnArr.push(function() {console.log(i);});}// 伪代码var fnArr;fnArr = [];{let i;i = 0;if(i < 3) {let i = i;fnArr.push(function() {console.log(i);})}i++;if(i < 3) {let i = i;fnArr.push(function() {console.log(i);});}i++;...}

是不是看出点名堂?其实我们完全可以这样理解,在每一次循环中都重新声明了i,并且被赋值为外层i的当前值。(注意啊,这里只是伪代码,便于理解,实际中let i = i是会抛出异常的)

转载于:https://www.cnblogs.com/innooo/p/10438947.html

ES6系列之let/const及块级作用域相关推荐

  1. ES6(一)——字面量的增强、解构、let/const、块级作用域、暂时性死区

    一.字面量的增强 ES6中对 对象字面量 进行了增强,称之为 Enhanced object literals(增强对象字面量). 字面量的增强主要包括下面几部分: 属性的简写:Property Sh ...

  2. var/let/const、块级作用域、TDZ、变量提升

    概览 ES6 新增了两个定义变量的关键字:let 与 const,它们几乎取代了 ES5 定义变量的方式:var.let是新的var,const简单的常量声明. function f() {{let ...

  3. java区块作用域_ES6-let、const和块级作用域

    1.介绍 总的来说,ES6是在ES2015的基础上改变了一些书写方式,开放了更多API,这样做的目的最终还是为了贴合实际开发的需要.如果说一门编程语言的诞生是天才的构思和实现,那它的发展无疑就是不断填 ...

  4. 详解var、let、const关键词声明变量的区别,以及变量提升、块级作用域的认识等。

    首先回顾一下JavaScript中var声明变量的基础知识: • 在使用var关键词声明变量时,变量在函数外则是全局变量,有全局作用域,全局变量在页面关闭后销毁:变量在函数内则是局部变量,作用局部作用 ...

  5. let、const和var的区别(涉及块级作用域)

    let .const和var的区别 let.const.var在js中都是用于声明变量的,在没有进行ES6的学习前,我基本只会使用到var关键字进行变量的声明,但在了解了ES6之后就涉及到了块级作用域 ...

  6. ES6规范前后块级作用域与函数声明的缠缠绵绵

    今天我们就以上面的这个例子来说一下,块级作用域与函数声明在ES6前后的纠葛,当然在ES6之前是没有块级作用域的,但为了与ES6统一,使文章更简明,所以把这对'{}'统一称为块级作用域. 开正题之前,还 ...

  7. ECMAScript6(1):块级作用域

    let.const和块级作用域 块级作用于对于强类型语言经验的人应该非常好理解, 一言以蔽之:ES5对变量作用于分隔使用了函数(词法作用域), 而ES6使用花括号(块作用域). 对于词法作用域在 ja ...

  8. 搭建Babel运行环境,Traceur ES6模板,块级作用域,let和const命令

    搭建Babel运行环境 Babel(http://babeljs.io/)可用于将使用ES6语法的脚本转化为ES5语法的脚本,基本功能的安装步骤如下: 1.安装node解释器和npm包管理工具 2.安 ...

  9. ES6基础2(块级作用域、数组对象解构)-学习笔记

    文章目录 ES6基础2(块级作用域.数组对象解构)-学习笔记 块级作用域 数组解构 对象解构 字符串解构 函数的参数解构 ES6基础2(块级作用域.数组对象解构)-学习笔记 块级作用域 //let c ...

  10. ES6中块级作用域下的函数声明

    背景 因为ES5的时候没有块级作用域,所以ES5规定不能再if这样的块中声明函数,但是为了兼容各大浏览器并没有严格遵守这条规定. ES6的时候引入了块级作用域,规定在块级作用域中声明函数就相当于使用l ...

最新文章

  1. 号外! 大维度机器学习也有计算框架了
  2. ELS多种方式集群部署
  3. 如何定位“Operating system error 32(failed to retrieve text for this error. Reason: 15105)”错误中被占用的文件...
  4. Web前端就业薪资是多少?Web前端要学什么?
  5. Where is number of opportunities not displayed message poped up
  6. mysql在linux下的安装_mysql在linux下的安装
  7. 埃及分数(信息学奥赛一本通-T1444)
  8. php开发手册pdf版,TP5.0手册下载
  9. 最大流(Maximum Flow)
  10. 小米、搜狗、TW等机器学习算法工程师面试总结
  11. Intelligent Reference Curation for Visual Place Recognition via Bayesian Selective Fusion 论文阅读及注解
  12. 在yandex投放广告的话,需要注册俄罗斯常用的域名吗?
  13. window10无法访问局域网共享文件夹
  14. Duilib corner属性
  15. C语言函数中的3个点 ...有什么作用
  16. Maximal Information Coefficient (MIC)最大互信息系数详解与实现
  17. Linux 进程管理之current
  18. 我国数字出版产业发展规模[中国新闻出版网]
  19. 李永乐复习全书概率论与数理统计 第一、二章 随机事件和概率、随机变量及其概率分布
  20. 中国移动苏州研发中心一面

热门文章

  1. 基于springboot的疫情网课教学平台
  2. 第八章(三)滑动窗口
  3. 计算机网络-应用层与传输层
  4. thinkphp5.x之数据库操作相关解析 Db类
  5. Java 控制 Windows 系统音量
  6. java socket php_Web架构(二)PHP Socket与Java ServerSocket交互
  7. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_17-页面静态化-模板管理-GridFS研究-存文件...
  8. Can not find the tag library descriptor for http://java.sun.com/jsp/jst1/core
  9. Centos 7.x 安装配置tomcat-8过程梳理
  10. 美化博客园 添加网易云音乐及生成文章目录