let 指令用法类似于 var,也是用来声明变量 ,但是它所声明的变量,只能在 let 指令所在的代码块内有效 。

{let a = 1;var b = 1;
}console.log(b);
console.log(a);
复制代码

运行结果:

1
console.log(a);^ReferenceError: a is not defined
复制代码

此例中, b 会打印出结果。但 a 因为是使用 let 命令声明的变量,所以只在它所在的代码块内有效。

1 应用场景

let 指令适用于 for 循环变量声明。在 ES6 之前,我们使用 var 指令来声明变量,可能存在一些问题,请看下面的示例:

var a = [];
for (var i = 0; i < 3; i++) {a[i] = function () {console.log(i);};
}
a[0]()
a[2]()
复制代码

运行结果:

3 3

变量 i 是 var 声明的,所以它在全局范围内都有效 。 所以在每一次循环中,新的 i 值都会覆盖旧值,导致最后 a 中的所有函数,输出的都是最后一轮的 i 的值 。

使用 let 指令,就能够避免上述问题:

var a = [];
for (let i = 0; i < 3; i++) {a[i] = function () {console.log(i);};
}
a[0]()
a[2]()
复制代码

运行结果:

0 2

注意: for 循环内部,设置循环变量是一个作用域,而循环体内部是另一个作用域:

for (let i = 0; i < 3; i++) {let i = 10;console.log(i)
}
复制代码

运行结果:

10 10 10

2 变量不提升

var 会发生 “ 变量提升 ” 现象,即 var 声明的变量,可以在声明之前使用。 但 let 声明的变量,一定要在声明之后使用,这种设计,让 JS 变得更加规范。变量在声明后,才能使用。

//var 变量提升
console.log('j='+j);
var j = 1;//let 变量不会提升
console.log('k='+k);
let k = 1;
复制代码

运行结果:

j=undefined ReferenceError: k is not defined

3 暂时性死区

只要块级作用域内,存在 let 指令,那么它所声明的变量不会再受外部影响,所以称为暂时性死区(temporal dead zone)。

var str = 1;
if (true) {str = 'a';let str;
}
复制代码

运行结果:

ReferenceError: str is not defined

ES6 中,如果代码块内存在 let 或 const 指令声明的变量,那么这些变量从一开始就会形成封闭作用域 。 凡在声明之前使用这些变量,就会抛出 ReferenceError。

3.1 对 typeof 的影响

暂时性死区甚至会影响到 typeof 操作符:

if(true){console.log('y 类型:'+typeof y);console.log('x 类型:'+typeof x);let x;
}
复制代码

运行结果:

y 类型:undefined ReferenceError: x is not defined

这个示例,变量 x 使用 let 指令声明,所以在声明之前,都属于 x 的暂时性死区 ,因此抛出了 ReferenceError 。

3.2 隐蔽的死区

请看这个示例:

function test(x = y, y = 1) {return x + y;
}
test();
复制代码

运行结果:

ReferenceError: y is not defined

函数的入参 x,它的默认值等于另一个入参 y ,而此时 y 还未声明,所以会抛出 ReferenceError。

只要声明了所有的入参,就可以让这个函数正确运行:

function test2(y = 1,x = y ) {return x + y;
}
console.log(test2());
复制代码

运行结果:

2


暂时性死区的设定,可以有效地减少运行时错误。它的本质是:在当前作用域下,只有声明了变量,才可以使用它。

4 拒绝重复声明

let 指令,在相同作用域内,同一个变量只能被声明一次。

if(true){let a = 1;var a = 2;
}
复制代码

运行结果:

SyntaxError: Identifier 'a' has already been declared

if(true){let a = 1;let a = 2;
}
复制代码

运行结果与上例相同。

这样的限制,也约束了函数的入参声明:

function test(a) {let a = 2;console.log(a);
}test(1);
复制代码

运行结果:

SyntaxError: Identifier 'a' has already been declared

但我们可以在函数内部,加入块级作用域,来绕开这一限制:

function test(a) {{let a = 2;console.log(a);}
}test(1);
复制代码

运行结果:

2

转载于:https://juejin.im/post/5d060c4ff265da1bb47d633a

说说 ES6 的 let 指令相关推荐

  1. 【Vue.js 知识量化】组件化开发 + 前端模块化

    Vue.js 组件化开发 组件化 认识组件化 注册组件 全局组件和局部组件 父子组件 组件数据 父子组件的通信 父->子:props 子->父:$emit() 父子组件的访问方式 $chi ...

  2. 【Vue全家桶+SSR+Koa2全栈开发】项目搭建过程 整合 学习目录(持续更新中)

    写在开头 大家好,这里是lionLoveVue,基础知识决定了编程思维,学如逆水行舟,不进则退.金三银四,为了面试也还在慢慢积累知识,Github上面可以直接查看所有前端知识点梳理,github传送门 ...

  3. es6 ... 添加属性_如何在10分钟内免费将HTTPS添加到您的网站,以及为什么您现在不止需要这样做......

    es6 ... 添加属性 by Ayo Isaiah 通过Ayo Isaiah 如何在10分钟内免费将HTTPS添加到您的网站,以及为什么现在比以往更需要这样做 (How to add HTTPS t ...

  4. ES6 之Reflect 与 Proxy概述

    Proxy 与 Reflect 是 ES6 为了操作对象引入的 API .Proxy 可以对目标对象的读取.函数调用等操作进行拦截,然后进行操作处理. 概述 Proxy 与 Reflect 是 ES6 ...

  5. ES6数组新增的几个方法

    关于数组中forEach() .map().filter().reduce().some().every()的总结 1.forEach() var arr = [1,2,3,4]; arr.forEa ...

  6. 工程实战-ES6环境配置

    最近在学习ES6语法,故有了从零开始搭建ES6环境的想法.下面第一部分是单纯的ES6环境配置,第二部分是基于webpack环境的工程配置 1. 纯ES6环境配置 1.1 packages中的依赖项: ...

  7. vue指令写在html中的原理,详解Vue中的MVVM原理和实现方法

    对Vue中的MVVM原理解析和实现首先你对Vue需要有一定的了解,知道MVVM.这样才能更有助于你顺利的完成下面原理的阅读学习和编写下面由我阿巴阿巴的详细走一遍Vue中MVVM原理的实现,这篇文章大家 ...

  8. NOP (code)_NOP指令作用及解析

    摘自:维基百科 NOP (code) 前言 在计算机科学中,NOP.no-op 或 NOOP(发音为"no op":no operation 的缩写)是一种机器语言指令及其汇编语言 ...

  9. ES6, Angular,React和ABAP中的String Template(字符串模板)

    String Template(字符串模板)在很多编程语言和框架中都支持,是一个很有用的特性.本文将Jerry工作中使用到的String Template的特性做一个总结. ES6 阮一峰老师有一个专 ...

最新文章

  1. 什么是类别不平衡?有哪些解决方案?
  2. 交换机短路_弱电工程中最常用的网络设备,网络交换机的种类有哪些
  3. TCP三次握手、糊涂窗口、粘包问题
  4. 3389端口远程终端服务的全攻略
  5. yara 模式匹配 android,YARA——恶意软件模式匹配利器
  6. C#将WebBowser控件替换为Chrome内核
  7. SQLi LABS Less 25 联合注入+报错注入+布尔盲注
  8. 细节真的能决定成败么?
  9. C++标准转换运算符:const_cast
  10. 开课吧:数据分析师常用的分析方法有哪些?
  11. android开发我的新浪微博客户端-载入页面UI篇(1.1)
  12. 【路径规划】基于matlab蚁群算法求解机器人栅格地图最短路径规划问题【含Matlab源码 1580期】
  13. Python——破解极验滑动验证码
  14. 稻盛和夫「活法」| 读书笔记系列01
  15. 早期微处理器相关的中文翻译书籍
  16. python人民邮电出版社_人民邮电出版社 - 主页
  17. PyCharm+Anaconda配置OpenCV4.4和PyQt5
  18. IOS9 xcode7 You must rebuild it with bitcode enabled
  19. 多大样本量才能模拟出中心极限定理
  20. Echart颜色设置

热门文章

  1. 基于springMVC拦截器实现操作日志统计
  2. Go语言之标志符可见性
  3. 阿里云中间件团队首次解密企业级分布式应用服务EDAS
  4. Android 4.4(KitKat)中的设计模式-Graphics子系统
  5. 成为人上人,而不是人上人永远的崇拜者
  6. SQLite的基本使用一
  7. 005 反转单链表(迭代递归)
  8. JS基础——循环很重要
  9. js技巧之与或运算符 || 妙用
  10. 存储过程传入参数与表字段名相同时产生的问题