let : 块级作用域
我们知道,JavaScript是没有块级作用域的,如果在块内使用var声明一个变量,它在代码块外面仍旧是可见的:
if (true) {
var foo = 3;
}
console.log(foo); // 3
for (var i = 0; i < 9; i++) {
var j = i;
}
console.log(i); // 9
console.log(j); // 8
可以看到,在上面代码中,我们虽然是在块内声明的变量,但代码块执行完毕后,依然可以访问到相应的变量,说明JavaScript中没有块级作用域的。
而ES6规范给开发者带来了块级作用域(终于跟 C,Java,Kotlin 等语言保持一致了),如果把var换成let命令,我们就可以获得一个块级变量:
if (true) {
let foo = 3;
}
console.log(foo); // Uncaught ReferenceError
for (let i = 0; i < 9; i++) {
let j = i;
}
console.log(i); // Uncaught ReferenceError
console.log(j); // Uncaught ReferenceError
从上面代码可以看出,块内声明的变量,块外是不可见的,如果试图引用一个块内用let声明的变量,就会引发一个异常。
let约束了变量提升, ES6中的let命令规范了变量的声明,约束了变量提升,也就是说,我们必须先声明,然后才可以使用: 永远将变量声明置于当前作用域顶部:
function nonHoistingFunc() {
let foo = 3;
console.log('foo:', foo); // 3
}
nonHoistingFunc();
const 变量: 引用不可变
以上let所介绍的规则均适用于const命令,不同的是,const声明的变量不能重新赋值。也就是 Java 中的 final,Kotlin 中的 val。
也是由于这个规则,const变量声明时必须初始化,不能留到以后赋值,所以下面的代码是不合法的:
const a = 3;
a = 5; // Uncaught TypeError: Assignment to constant variable
const b; // Uncaught SyntaxError: Missing initializer in const declaration
以上就是let和const的内容,可以看出,let和const大大改进了ES5的变量机制,使得JS更严谨和规范,随着ES6支持程度的提高,我们应该开始习惯let和const的使用了。
参考资料:
http://es6.ruanyifeng.com/#docs/let
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const