1.var定义的变量,没有块的概念,可以跨块访问,不能跨函数访问。
2.let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
3.const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。
// 一、var声明的变量会挂载在window上,而let和const声明的变量不会
var a = 1;
console.log(a,window.a);
let b = 2;
console.log(b,window.b);
const c = 3;
console.log(c,window.c);
// 二、var声明变量存在变量提升,let和const不存在变量提升
console.log(a);
var a = 1;
console.log(b);
let b = 1;
console.log(c);
const c = 1;
关于 var
在ES5中,顶层对象的属性和全局变量是等价的,用var声明的变量既是全局变量,也是顶层变量。
如果使用关键字 var 声明一个变量,那么这个变量就属于当前的函数作用域,如果声明是发生在任何函数外的顶层声明,那么这个变量就属于全局作用域。
例如:
var a = 1; //此处声明的变量a为全局变量
function foo(){
var a = 2;//此处声明的变量a为函数foo的局部变量
console.log(a);//2
}
foo();
console.log(a);//1
如果在声明变量时,省略 var 的话,该变量就会变成全局变量,如全局作用域中存在该变量,就会更新其值。
var a = 1; //此处声明的变量a为全局变量
function foo(){
a = 2;//此处的变量a也是全局变量
console.log(a);//2
}
foo();
关于let
let是ES6新增的命令,用来声明变量
let 声明的变量,具有如下几个特点:
-
let 声明的变量具有块作用域的特征。
-
在同一个块级作用域,不能重复声明变量。
-
let 声明的变量不存在变量提升,换一种说法,就是 let 声明存在暂时性死区(TDZ)。
例如: let a = 1; console.log(a);//1 console.log(b);//Uncaught ReferenceError(未捕获的的参数错误): b is not defined let b = 2; function foo(){ let a = 1; let a = 2;// 标识符“a”已经被声明 }
关于const
1、一旦声明必须赋值。
2、声明后不能再修改
3、如果声明的是复合类型数据,可以修改其属性
例如:
const a = 1;
console.log(a);//1
a = 2;
console.log(a);//赋值给常变量。
const 声明的变量其内部内容是可变的
例如:
const obj = {a:1,b:2};
console.log(obj.a);//1
obj.a = 3;
console.log(obj.a);//3
区别
变量提升
var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined
let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错
varconsole.log(a) // undefined
var a = 10
let console.log(b)
块级作用域
var不存在块级作用域
let和const存在块级作用域
暂时性死区
var不存在暂时性死区
let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
重复声明
var允许重复声明变量
let和const在同一作用域不允许重复声明变量
修改声明的变量
var和let可以
const声明一个只读的常量。一旦声明,常量的值就不能改变
使用
能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var