1 .ES6 新增了let
命令,用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。
2.let 命令比较适合用于for循环,可以避免污染全局 。如下例:
for(var i=0;i<10;i++) {}
console.log(i) //10
for(let i=0;i<10;i++){}
console.log(i) //ReferenceError
3另外 使用var、let 执行相同的一段代码,结果可能是不同的 ,如下例:
var a=[ ]
for(var i=0;i<10;i++){ for(let i =0;i<10;i++) { a[ i ] = function() { console.log( i) } }
a[ i ] = function() { console.log( i) } a[ 6 ] () // 6
}
a[ 6 ] () //10
解释:用var 声明的是全局变量·,所以i只有一个 ,所有数组a
的成员里面的i
,指向的都是同一个i
,导致运行时输出的是最后一轮的i
的值,也就是 10。
如果使用let
,声明的变量仅在块级作用域内有效,最后输出的是 6。
4 .另外,for
循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
for( let i=0;i<10;i++) {
let i='hello world'
console.log( i) // hello world
}
5 .var
命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined
。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
6. 只要块级作用域内存在let
命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var box=123;
if(true){
box='abc' //ReferenceError
let box=qwe
}
上面代码中,存在全局变量tmp
,但是块级作用域内let
又声明了一个局部变量tmp
,导致后者绑定这个块级作用域,所以在let
声明变量前,对tmp
赋值会报错。
ES6 明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
7 在没有let 以前 typeof是很安全的 但有了let后 不再是安全的了。如下例:
typeof x ; //ReferenceError
let x