let
不发生变量提升
-
暂时性死区
块内使用let声明的变量在还没有声明前使用会报错var tmp = 123
if (true) {
tmp = 456 // ReferenceError!
let tmp
tmp = 789 // Okay~
} 禁止重复声明
function () {
let a
let a // already declared...
}
块级作用域
- 内层覆盖外层
var tmp = 1
function f() {
console.log(tmp)
if (false) {
var tmp = 2 // 在函数作用域中发生了提升
}
}
f() // undefined
- 循环计数变量泄漏
for (var i = 0; i < 10; i++) { /* do something... */ }
console.log(i) // 11
ES6新增了块级作用域,一个块就是一个大括号括起的区域。
function f() {
let n = 5
if (true) {
let n = 10 // 块内独立
}
console.log(n) // 5
}
const
const用于声明常量。必须立即初始化;不发生提升;存在暂时性死区。
const实际上只保证指向的地址不变,不保证指向的内容不变。例如const a = {}; a.x = 1;是允许的,但是a = 1是禁止的。
如果要禁止对象的修改,可以使用Object.freeze(obj)方法来冻结。
顶层对象
- 浏览器下,最外层的var声明变量会全部绑到window上,但let、const不会
- Node的顶层对象是global