在ES6中新增了两种定义变量的命令let和const,在这之前相信大家都对var定义变量很熟悉,那么在了解ES6方法前,
1.我们先来回顾一下var定义变量的方法。
下面来看这段代码:
for (var i = 0; i < 10; i++) {
console.log(i);
}
alert(i)
在javascript中没有块级作用域,在for()里面定义变量i ,在循环外部依然可以进行正常访问。var定义变量还有一个问题如下:
var i = 15;
var i = 5;
alert(i);//5
其中变量i重复定义没有报错,反而输出值为5,说明被复写了。用var定义变量还存在一个问题如下:
for (var i = 0; i < 3; i++) { setTimeout(function () { console.log(i) }, 1000); }
输出结果为3,3,3,因为当循环结束时,i的值为三。所以在执行setTimeout函数时会打印三次3。(注释,如果将var替换成let就不会出现这个问题)
2. 在介绍完var后,我们来学习下ES6中的两种定义变量的命令,首先来学习let:
ES6 新增了let
命令,用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。请看下面代码
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
for
循环的计数器,就很合适使用let
命令。
for (let i = 0; i < 10; i++) { // ... } console.log(i); // ReferenceError: i is not defined
上面代码中,计数器i
只在for
循环体内有效,在循环体外引用就会报错。说明:使用let
,声明的变量仅在块级作用域内有效;
var
命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined
。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。为了纠正这种现象,let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
// var 的情况console.log(foo); // 输出undefined var foo = 2; // let 的情况 console.log(bar); // 报错ReferenceError let bar = 2;
上面代码中,变量foo
用var
命令声明,会发生变量提升,即脚本开始运行时,变量foo
已经存在了,但是没有值,所以会输出undefined
。变量bar
用let
命令声明,不会发生变量提升。这表示在声明它之前,变量bar
是不存在的,这时如果用到它,就会抛出一个错误。说明:ES6 明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。总之,在代码块内,使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
3.下面来讲解const:
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
const PI = 3.1415;PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
上面代码表明改变常量的值会报错。const
声明的变量不得改变值,这意味着,const
一旦声明变量,就必须立即初始化,不能留到以后赋值。
const foo;// SyntaxError: Missing initializer in const declaration
上面代码表示,对于const
来说,只声明不赋值,就会报错。const
的作用域与let
命令相同:只在声明所在的块级作用域内有效。
if (true) { const MAX = 5; } MAX // Uncaught ReferenceError: MAX is not defined
const
命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
if (true) { console.log(MAX); // ReferenceError const MAX = 5; }
上面代码在常量MAX
声明之前就调用,结果报错。const
声明的常量,也与let
一样不可重复声明。
var message = "Hello!"; let age = 25; // 以下两行都会报错 const message = "Goodbye!"; const age = 30;