ES6语法——let const var 声明变量的区别

var声明变量的特点

1-var存在变量提升和预解析

2-var没有块级作用域

let声明变量的特点

1-let 声明变量存在块级作用域
  这个经典的例子就是for循环里面的应用了

2-let 声明变量没有变量提升
  使用let声明的变量不会出现像var那样存在“变量提升”现象。但本质上,二者是相同的,它们都会在初始化时先初始化属性,再初始化逻辑,然而二者的区别在于使用let声明的变量虽然一开始就存在,但是不能使用,而使用var声明的变量则可以。

3-let 存在死区
  只要块级作用域内存在let命令,它所声明的变量就绑定在这个区域,不再受外部影响
  ES6明确规定,只要块级作用域中存在let命令,则这个块区对这些命令声明的变量从一开始就形成封闭的作用域。只要声明之前,使用这些变量,就会报错。这样说有些抽象,只需要记住:在块级作用域内如果使用let声明了某个变量,那么这个变量名必须在声明它的语句后使用,从块开头到声明变量的语句中间的部分,称为这个变量的“暂时性死区”。
  因此let声明的变量一定要在声明之后使用

4-let 不允许重复声明
  let不允许在相同作用域内重复声明同一个变量,即同一个作用域内不允许出现名称相同的变量。比如下面几种形式,不能同时出现:

这里特别需要注意的是函数形参的问题

5-let 全局对象的属性

  在ES5中,全局对象的属性和全局变量是等价的。ES6规定,使用var, function声明的全局变量依旧作为全局变量window的属性存在,而使用let,const,class声明的全局变量则不属于全局变量window的属性。

const声明变量的特点

  1- const与let的特性基本相同,但顾名思义,const用于声明常量,一旦声明,必须立即赋值,且以后不可更改。
  2- 使用const声明对象的时候,只能保证对象的引用地址不被更改,并非此对象不被修改。也就是说const声明的常量是引用这个对象的地址不会变(就是引用关系不会变),但是储存在堆内存的对象里面的内容可以进行更改。如果你真的想保证对象绝对安全,可以使用Object.freeze方法:将对象进行冻结
  3- const 声明的变量和let声明的变量一样,也存在块级作用域,也有死区,也不会进行变量提升

小结

  let可以完全取代var,因为二者作用几乎相同,且let没有任何副作用。在let和const之间,优先使用const,尤其是只应该设置常量的全局环境。大部分的函数一旦定义就不会改变(除了使用初始化分支的方式覆写函数的时候),所以,我们一般推荐使用const来声明一个函数。最后,V8只在严格模式下支持let和const的声明方式。