本文是学习阮一峰《ECMAScript 6 入门》 let 命令部分的笔记。
基本用法
let
命令,用来声明变量,用法类似于 var
,但是所声明的变量,只在 let
命令所在的代码快内有效;
|
|
let命令在for循环中的应用
a. for循环的计数器
|
|
计数器 i
只在 for
循环内有效,在循环外引用就会报错。
b. for循环内声明的变量
|
|
变量 i
是 let
声明的,当前的 i
只在本轮循环中有效,所以每次循环的 i
其实就是一个新的变量。而 JavavScript 引擎内部会记住上一轮循环的值,初始化本轮的变量 i
时,就会在上一轮循环的基础上进行计算,所以最后输出的结果是 6
。
c. for
循环的父作用域和子作用域for
循环有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
|
|
以上代码运行结果输出三次 “abc”
, 这表明函数内部的变量 i 与循环变量 i
不在同一个作用域,有各自单独的作用域。
不存在变量提升
“变量提升”: 变量可以在声明之前使用,值为undefined
。—— var
命令
let
命令:规定声明的变量一定要在声明后使用,否则报错。
|
|
暂时性死区
在代码块内,使用 let
命令声明变量之前,该变量就是不可用的。这在语法上,称为 “暂时性死区”(temporal dead zone,简称TDZ)。
只要块级作用与内存在 let
命令,它所声明的变量就 “绑定” 在这个区域,不再受外部的影响。
|
|
上面代码中,一开始声明了一个全局变量 tmp
,但是块级作用域内 let 又声明了一个局部变量 tmp
,导致 tmp
变量绑定在这个块级作用域内。
所以,块级作用域内,在 let
声明变量之前,都属于 tmp
变量的 “暂时性死区”,会报错。
typeof不再百分之百安全
|
|
变量 x
使用 let
命令声明,所以在声明之前,都属于变量 x
的“暂时性死区”,只要用到变量 x
就会报错。而变量 y
没有被声明,使用 typeof
反而不会报错,返回“undefined”
。
隐蔽的“暂时性死区”
|
|
第一个函数 test0
中,调用时候报错的原因是:参数 x
默认值等于另外一个参数 y
,而此时 y
还没有声明,属于“死区”。如果 y
的默认值是 x
,就不会报错,因为此时 x
已经声明了。
第二个函数 test1
中,参数 x
的默认值为 2
,参数 y
的默认值等于参数 x
,而此时 x
已经声明了,所以不会报错。
|
|
ES6规定暂时性死区和 let
、const
语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明之前就使用这个变量,从而导致意料之外的行为。
暂时性死区的本质: 只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
不允许重复声明
let
不允许在相同的作用域内,重复声明同一个变量。(在函数内不能重复声明参数)
|
|
现在与前面 for 循环的父作用域和子作用域进行对比
|
|
这两个变量 i
虽然是在同一次循环当中,但他们的作用域不同,计数器 i
位于父作用域,而循环体内部的变量 i
位于子作用域,所以这里不会报错。(千万不要以为这也是在同一个作用域内重复声明变量)