1. var
在ES5中,顶层对象的属性和全局变量是等价的,用var声明的变量即是全局变量,也是顶层变量,在浏览器中顶层对象指的是window对象,在node中顶层对象指的是global对象。
console.log(a) // undefined
var a = 1
console.log(window.a) // 1
function get() {
var a = 2
b = 3 // 全局变量
}
get()
console.log(a) // 1
{
var c = 3
}
console.log(c) // 3
使用var存在变量提升;
使用var能够对一个变量进行多次声明,后面声明的变量会覆盖前面的变量声明;
在函数中使用var声明变量时候,该变量是局部的,而如果在函数内不使用var则该对象是全局的;
2. let
let是ES6新增的命令用来声明变量,用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,不存在变量提升,只要块级作用域内存在let命令,这个区域就不再受外部影响,并且let不允许在相同的作用域中重复声明;
也不能在函数内部重新声明参数;
{
console.log(a) // 报错referenceError
let a = 1
let a = 2 // uncaught SyntaxError: a has already been declared
}
console.log(a) // referenceError: a is not defined
function get(arg) {
let arg
}
get() // uncaught SyntaxError: arg has already been declared
3. const
const声明一个只读变量,一旦声明,常量的值就不能改变;这就意味着const一旦变量声明,就必须立即初始化,不能留到以后赋值;
const a = 1
a = 2 // typeError: assigment to constant variable
const obj = {}
obj.a = 1
obj = {} // typeError: obj is read-only
const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动,对于简单类型的数据,值就保存在变量指向的那个内存地址,对于复杂类型的数据,变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的,并不能确保改变量的结构不变。
4. 区别
- 变量提升:var可以变量提升,let和const不存在变量提升;
- 暂时性死区:var不存在暂时性死区,let和const存在暂时性死区,只有等到变量声明的那一行代码出现,才可以获取和使用变量;
- 块级作用域:var不存在块级作用域,let和const存在块级作用域;
- 重复声明:var可以重复声明变量,let和const不允许重复声明变量;
- 修改声明的变量:var和let可以修改,const声明一个只读的常量,一旦声明,常量的值就不能改变;
- 使用场景:能用const的情况尽量使用const,其他情况下大多数属于let,避免使用var。