一、前提
解决ES5中只有全局作用域和函数作用域,没有块级作用域而带来的不合理的场景。
let
基本用法
用法和var 一样,只是let声明的变量只有在let命令所在的代码块有效
{ let a = 10; var b = 1;}a // ReferenceError: a is not defined.b // 1
可以看出var 声明的变量在代码块之外也是可以调用,而let声明的则调用报错。所以let 声明只在它声明的当前代码块中才能调用。
变量提升
在使用 var 的时候会出现 “变量提升”的现象,即变量可以在声明之前使用,值为undefined。let 改变了这种现状,但是必须先声明在使用,如果在声明之前使用则会出现报错。如下:
// var 的情况console.log(foo); // 输出undefinedvar foo = 2;// let 的情况console.log(bar); // 报错ReferenceErrorlet bar = 2;
暂时性死区
只要块级作用域内部存在 let 或者 const 命令,它所声明的变量就“绑定”在这个区域,不会受外部影响。且暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。如下:
var tmp = 123;if (true) { tmp = 'abc'; // ReferenceError let tmp;}
ES6 明确规定,如果区块中存在 let 和 const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。如下:
if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123}
注意:
++使用let声明变量时,只要变量在还没有声明完成前使用,就会报错。上面这行就属于这个情况,在变量x的声明语句还没有执行完成前,就去取x的值,导致报错”x 未定义“。++
不允许重复声明
let 不允许在同一个作用域内声明同一个变量,如下:
// 报错function func() { let a = 10; var a = 1;}// 报错function func() { let a = 10; let a = 1;}
或者如下:
function func(arg) { let arg;}func() // 报错function func(arg) { { let arg; }}func() // 不报错
块级作用域
上面也提到过在es5中没有块级作用域的概念,只有函数作用域和全局作用域,那么就带来了一些问题,如下:
新闻热点
疑难解答
图片精选