let命令
ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。例如
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
for (let i = 0; i < 10; i++) {}
console.log(i);
//ReferenceError: i is not defined
//let定义只在for循环内有效,循环体外就会报错
不存在变量提升
let不像var那样会发生变量提升现象,所以不能先使用后声明
console.log(foo); // 输出undefined
console.log(bar); // 报错ReferenceError
var foo = 2;
let bar = 2;
不允许重复声明
let不允许在相同作用域内重复声明同一个变量
// 报错
function () {
let a = 10;
var a = 1;
}
// 报错
function () {
let a = 10;
let a = 1;
}
在函数内不能重新声明参数
function func(arg) {
let arg; // 报错
}
function func(arg) {
{
let arg; // 不报错
}
}
新增块级作用域
在ES5中只有全局作用域和函数作用域,没有块级作用域,let为JS新增块级作用域
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
上面的代码运行后会输出5,就是if语句内的变量声明不受外部的影响,如果使用var来声明,结果就是10了。
ES6允许块级作用域的任意嵌套
{{{{{let insane = 'Hello World'}}}}};
{{{{
{let insane = 'Hello World'}
console.log(insane); // 报错
}}}};
const命令
const用来声明一个只读的常量,一旦声明,常量的值不可改变,且一旦声明就必须立即初始化,不可留到以后赋值
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
const foo;
// SyntaxError: Missing initializer in const declaration
const的块级作用域与let相同且不会有变量提升,只能在所在的块级作用域内有效,这里就不一一举例。
对于复合型的变量,变量名不指向数据所在的地址,const命令只是保证变量名指向的地址不变,并不能保证地址的数据不变,所以将一个对象声明为常量必须非常小心。
const foo = {};
foo.prop = 123;
foo.prop
// 123
foo = {}; // TypeError: "foo" is read-only
上面代码中,常量foo储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。再看另一个例子
const a = [];
a.push('Hello'); // 可执行
a.length = 0; // 可执行
a = ['Dave']; // 报错
上面代码中,常量a是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给a,就会报错。
如果真的想将对象冻结,应该使用Object.freeze方法。
const foo = Object.freeze({});
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;