基本用法
ES新增了let命令,用于声明变量。其用法类似于var,但是所声明的变量只在let命令所在的代码块中有效。
for(let i = 0;i<5;i++) {}
console.log(i);//ReferenceError:i is not defined
而下面代码的var作用就是全局
for (var i = 0; i < 5; i++) {}
console.log(i);//5
如果将console.log(i)放在{}中,ES6将会输出6
不存在变量提升
let不像var那样会发生“变量提升”现象。所以,变量一定要在声明后使用,否则报错。
console.log(foo);//ReferenceError
let foo=2;
这也意味着typeof不再是一个百分之百安全的操作。
typeof x;//ReferenceError
let x;
暂时性死区
只要块级作用域内存在let命令,他所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var tmp = 123;
if(true) {
tmp = 'abc';
let tmp;
}
上面的代码中存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
ES6明确规定,如果区块中存在let和const命令,则这个区块对这些命令声明的变量从一开始就会形成封闭作用域。
function bar(x = y,y = 2) {
return [x,y];
}
bar();//[2,2]
上面的代码中,调用bar函数之所以报错,是因为参数x的默认值等于另一个参数y,而此时y还没有声明,属于死区。如果y的默认值是x就不会报错,因为此时X已经声明。
不允许重复声明
let不允许在xia相同作用域内重复声明同一个变量
//报错
function(){
let a = 10;
var a = 5;
}
//报错
function(){
let a = 10;
let a = 5;
}
因此不能在函数内部重复声明
function f(arg) {
let arg;//报错
}
function f(arg) {{
let arg;//不报错(这个可以理解为let arg是f(arg中的一块吗))
}}