概述
let 、const 是es6中新增的变量声明方式。与var关键字声明相同
特点
1.局部作用域
使用let、const声明的变量只在该变量所在的代码块中有效。也就是说代码块(局部作用域)中let或const声明的变量无法被外部访问。但内层作用域中的变量可以访问到外层中声明的变量。
例1
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
例2
for (let i = 0; i < 10; i++) {}
console.log(i);
//ReferenceError: i is not defined
例1上面代码在代码块之中,分别用let和var声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。(const相同)
例2代码中,计数器i只在for循环体内有效,在循环体外引用就会报错。
2.不存在变量提升
·变量提升是说函数及变量的声明都将被提升到函数的最顶部。也就是说函数及变量可以先使用后声明!
·在使用let或const声明的变量必须先声明后使用,如果先使用后声明则会报错,出现暂时性死区。
·内部作用域中let或const声明的变量不会覆盖到父级作用域中用let或const声明相同的变量。也就是说父子级中声明的相同名字的变量是相互独立、互不影响的。
typeof x; // ReferenceError
let x;
上面代码中,变量x使用let命令声明,所以在声明之前,都属于x的“死区”,只要用到该变量就会报错。因此,typeof运行时就会抛出一个ReferenceError。
3. 不允许重复声明
let不允许在相同代码块(作用域)内,重复声明同一个变量。
(在以上说明属于let 、const共有特性)
(函数声明具体规则将在函数文章中进行整理)
独特的const
·const声明一个只读的常量。一旦声明,常量的值就不能改变。一旦声明变量,就必须立即初始化,不能留到以后赋值。
·在用const声明的复合型变量时必须非常小心。因为变量名不指向数据,而是指向数据所在的地址。const命令只是保证变量名指向的地址不变,并不保证该地址中的数据不变。
当const声明为复合变量时
例1
const foo = {};
foo.prop = 123;
foo.prop // 123
foo = {}; // TypeError: "foo" is read-only
例2
const a = [];
a.push('Hello'); // 可执行
a.length = 0; // 可执行
a = ['Dave']; // 报错
例子中常量是复合类型。储存的是一个地址,这个地址指向一个‘复合类型’的常量。不可变的只是这个地址,即不能把这个‘复合类型’的常量指向另一个地址,但这个‘复合类型’的常量本身是可变的,所以依然可以为其添加新属性。将另一个‘复合类型’的常量赋值给这个‘复合类型’的常量,就会报错。
!!!如果声明的常量不许操作修改,可以使用Object.freeze();
const foo = Object.freeze({});
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;