1. let命令

基本用法

用来声明变量,类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

  1. {
  2. let a = 10;
  3. }

for循环的计数器很适合let命令,循环体外,声明的变量被引用时会报错。
for循环,设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

  1. for(let i=0;i<3;i++){
  2. let i = 'abc';
  3. console.log(i);
  4. }
  5. //输出
  6. //abc
  7. //abc
  8. //abc

不存在变量提升

let命令声明的变量一定要在声明后使用,否则报错。var声明的变量可以在声明之前使用,值为undefined。

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就是“绑定”(binding)在这个区域,不受外部影响。
例如,

  1. var tmp = 123;
  2. if(true){
  3. tmp = 'abc'; //报错,ReferenceError
  4. let tmp;
  5. }

ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
这在语法上称为“暂时性死区”(temporal dead zone,简称TDZ)。

不允许重复声明

let不允许在相同作用域内,重复声明同一个变量。

2.块级作用域

  • ES6允许块级作用域的任意嵌套。
  • 内层作用域可以定义外层定义域的同名变量。
  • 外层作用域无法读取内层作用域的变量。
  • ES6允许在块级作用域中声明函数,但在块级作用域之外不可引用。为了兼容,会出现提升的可能。

    3.const命令

    基本用法

  • const声明一个只读的常量。

  • const的作用域与let命令相同:只在声明所在的块级作用域内有效。
  • 同样存在暂时性死区。
  • 本质
  • const实际上保证变量指向的内存地址所保存的数据不得改动。
  • 常量对象可以添加新属性,因为不可变的是地址,对象本身是可变的。
  • 如果想将对象冻结,可以使用Object.freeze方法。

    4.顶层对象的属性

    顶层对象,在浏览器环境指的是window对象,在Node指的是global对象。ES5之中,顶层对象的属性与全局变量是等价的。
    ES6中,var和function命令声明的全局变量依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量不属于顶层对象的属性。