let
- 不存在变量提升,有暂时性死区,引用前需提前声明
- 同一作用域内不能重复声明
- 其声明的的全局变量不属于顶层对象的属性
const
- 不存在变量提升,有暂时性死区,引用前需提前声明
- 只能在声明时赋值
- 同一作用域内不能重复声明
- 不能重复赋值
- 赋值为基本类型,则不能修改;赋值为引用类型,则可修改(若希望将对象冻结,可以使用Object.freeze()方法)
- 其声明的的全局变量不属于顶层对象的属性
tips
变量提升:
类比函数声明提升:函数声明来定义函数即可实现函数声明提升,这样,我们可以先调用函数,后声明函数;而函数表达式方法不会实现函数声明提升,这样,如果先调用函数,后声明函数,则会抛出错误。那么可以以此类推,var定义变量:可以先使用,后声明;而let、const定义变量:只可先声明,后使用
暂时性死区:
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
块级作用域:
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。第一种场景,内层变量可能会覆盖外层变量。第二种场景,用来计数的循环变量泄露为全局变量。
ES6的块级作用域,允许块级作用域的任意嵌套,内层作用域可以定义外层作用域的同名变量。块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。
顶层对象:
顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象。ES5 之中,顶层对象的属性与全局变量是等价的。ES6 之中,为了保持兼容性,var和function声明的全局变量,依旧是顶层对象的属性;let、const、class声明的全局变量,不属于顶层对象的属性。