要定义变量,可以使用var操作符,后跟变量名
ES实现变量初始化,因此可以同时定义变量并设置它的值
使用var操作符定义的变量会成为包含它的函数的局部变量。
在函数内定义变量时省略var操作符,可以创建一个全局变量
如果需要定义多个变量,可以在一条语句中用逗号分隔每个变量
使用var声明的变量会自动提升到函数作用域顶部,这叫做提升
反复多次使用var声明同一个变量也没有问题
let声明的范围是块作用域,而var声明的范围是函数作用域,块作用域是函数作用域的子集
let也不允许同一个块作用域中出现冗余声明,这样会报错,嵌套使用相同的标识符不会报错,而这是因为同一个块中没有重复声明
对声明冗余报错不会因混用let和var而受影响,这两个关键字声明的并不是不同类型的变量,他们只是指出变量在相关作用域如何存在
let与var的另一个重要的区别,就是let声明的变量不会在作用域中被提升。在解析代码时,JS引擎也会注意出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量。在let声明之前的任何瞬间被称为暂时性死区,在此阶段引用任何后面才声明的变量都会报错
与var关键字不同,使用let在全局作用域中声明的变量不会成为window对象的属性,var声明的变量则会。不过let声明仍然是在全局作用域中发生的,相应变量会在页面的生命周期内存续
在使用var声明变量时,由于生命会被提升,JS引擎会自动将多余的声明在作用域顶部合并成一个声明。因为let作用域是块,所以不可能检查前面是否已经使用let声明过同名变量,同时也就不可能在没有声明的情况下声明它,为此,对于let关键字,不能依赖条件声明模式
在let出现之前,for循环定义的迭代变量会渗透到循环体外部,改成let后,迭代变量的作用域仅限于for循环快内部
在使用let声明迭代变量时,JS引擎在后台会为每个迭代循环声明一个新的迭代变量
const的行为与let基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误
const声明的限制只适用于它指向的变量的引用,如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制
不能用const生命迭代变量,因为迭代变量会自增,for-of和for-in可以
有助于提升代码质量的最佳实践:不使用var,const优先,let次之