提出
var是ES5提出的,let和const是ES6提出的。
作用域不同
let和const具有块级作用域,var不存在块级作用域,可以跨块访问, 不能跨函数访问
// 全局
var a = 10
console.log(a) // 10const test = (c) => {var b = 20console.log(b) // 20,这个b在函数内声明console.log(c)
}test(10) // 20 10
console.log(b) // 报错,b没有被声明
什么是全局作用域、函数作用域?
在ES6之前,作用域只有两种:全局作用域和函数作用域。var声明的变量存在于这两个作用域中。
全局作用域中的对象在代码的任何地方都能访问。
函数作用域就是在函数内部定义的变量或者函数,并且定义的变量或者函数只能在函数内部被访问。而且函数执行结束之后,函数内部定义的变量会被销毁。
什么是块级作用域?
用 { } 包裹的一段代码,如函数、判断语句、循环语句、甚至单独的一个 { }:
// 函数块
function fun() {}// 判断语句块
if(true) {}// 循环语句块
while(true) {}
for(let i=0; i<10; i++) {}// 单独一个块
{}
全局属性
var是全局的,window.a
var可以重复声明变量,后声明的变量会覆盖先声明的
变量提升
var存在变量提升;let和const不存在变量提升。
什么是变量提升?
允许在变量声明之前即被访问。
在代码执行之前,把当前作用域中var声明的变量全部提到当前作用域的最前面。
只提升声明,不提升变量。
function fn(){console.log(num)var num = 10
}
相当于以下代码:
function fn(){var numconsole.log(num)//undefinedvar num = 10
}
变量num在var声明之前即被访问,变量的值为undefined。
初始值设置
在变量声明时,var 和 let 可以不用设置初始值。而const声明变量必须设置初始值。
var a
let b
const c//错误,需要改为const c = 30
重复声明
var声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的遍历;
const和let不允许重复声明变量。
var a = 1;
var a = 2;
console.log(a);//输出2
可修改性
const声明的变量是常量,值不可修改;var和let声明的变量的值可以修改。
给全局添加属性
var声明的变量会挂载到window上;let和const声明的变量则不会。
var a = 1;
console.log('a', window.a);//a 1let b = 2;
console.log('b', window.b);//b undefinedconst c = 3;
console.log('c', window.c);//c undefined
暂时性死区
定义:let/const 命令会使区块形成封闭的作用域。若在声明之前使用变量,就会报错。
在代码快内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”。
结论:var不存在暂时性死区,let和const存在暂时性死区。