var、let定义了一个变量,我们可以修改它的类型和值。
const定义的是一个常量,可以修改类型,但不能改变它的值;
let 和 const 是ES6新增的关键字
var 关键字
var 声明的变量是 window 的属性;
var 关键字声明之后如果没有初始化,那么它的值为 undfined ;
var 声明的变量会被提升到作用域的顶部(但是赋值操作不会),如果有操作在var声明该变量之前引用该变量,会得到undfined,而不会报错;
var 关键字可以重复声明同一个变量,重复声明的操作相当于给该变量重新赋值;
在函数体中,var定义的变量是一个局部变量,他的作用域在整个函数内部都有效,在函数结束退出时var声明的变量才被销毁;
在外部,var 声明的变量相当于全局变量。
let 关键字
let 声明的变量不是 window 的属性;
暂时性死区:let不具有声明提升的作用,所以如果在函数内有操作在 let 声明之前引用了该变量将会报错;
let 声明的变量为块作用域,即在花括号内用 let 声明的变量只在花括号内有效,出花括号即被销毁;
let 在同一块作用域不能重复声明相同的变量,在花括号的子花括号内重复声明是允许的,因为子花括号内声明的变量不会传递出子花括号。
const 关键字
const 关键字定义了一个常量,一旦声明常量的值无法更改;
const 无法重复声明同一个常量;
const 声明的常量的作用域也是一个块作用域;
对于 const 声明的常量表达的是对象、数组等时,因为该常量保存的是它们的地址,所以我们只要不改变对象或数组的地址,其实他们内部的属性是可以改变的。
var、let、const的区别主要源于 ES6 规范中的一个词 Global Enviroment records (全局环境变量记录),它里面包含了两个内容,一个是 Object Enviroment records ,另一个是 Reclarative Enviroment records ,函数声明 var 时会加入Object Enviroment records ,并且先检查 Reclarative Enviroment records ,如果该纪录中不存在,那么就会将 var 声明的变量记录到 Object Enviroment records ,函数 let 和 const 声明的变量会先检查两个记录中是否存在,都不存在才会加入到Reclarative Enviroment records 记录中,这就是为什么 let 和 const 不能重复声明变量的原因;
let 其实也可以提升的声明,但是因为提升了,但是变量未初始化,所以引用该变量的操作读不出来 let 声明的变量的值,所以会报错;