一、let 命令
- es6新增了let命令,用来声明变量,用法类似于var,let命令只在所在的代码块里有效。
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
可以清楚的看到,let变量报错,var则没事。
- 不存在变量提升
//var
console.log(foo); // 输出undefined
var foo = 2;
//let
console.log(bar); // 报错ReferenceError
let bar = 2;
3.暂时性死区
只要块级作用域内存在let命令,它所声明的变量就 “绑定” 这个区域,不再受外部的影响。
var tmp = 123;
if(true){
tmp='abc'; //ReferenceError
let tmp;
}
上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
“暂时性死区”也意味着typeof不再是一个百分之百安全的操作。
typeof x; // ReferenceError
let x;
在变量x的声明语句还没有执行完成前,就去取x的值,导致报错”x 未定义“
let x = x; // ReferenceError: x is not defined
有些“死区”比较隐蔽,不太容易发现。例如
function bar(x = y, y = 2) {
return [x, y];
}
bar(); // 报错
在参数y没有声明前就被x调用
4.不允许重复声明
let不允许在相同作用域内,重复声明同一个变量。
// 报错
function func() {
let a = 10;
var a = 1;
}
// 报错
function func() {
let a = 10;
let a = 1;
}
再代码块中这两种情况都会报错。
5.let为 JavaScript 新增了块级作用域。
function f (){
let n = 5;
if(true){
let n =10;
}
console.log(n); //5
}
二、const命令
1.const声明一个只读的常量。一旦声明,常量的值就不能改变
const p = 3.1415;
p // 3.1415
p = 1;
// TypeError: Assignment to constant variable.
2.const一旦声明变量,就必须立即初始化
const foo;
// SyntaxError: Missing initializer in const declaration
3.const的作用域与let命令相同:只在声明所在的块级作用域内有效。
4.const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。