一、基本用法
var
和let
都用于声明变量,let
是ES6中新增的定义方式
var a=1;
let b=2;
两个语法相同,区别如下
二、区别
1. 作用域
块作用域:块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域
var
定义的变量有 函数作用域或全局作用域(定义在函数中/全局),没有块的概念
let
定义的变量 只能在块作用域里访问
function varTest() {
var x = 1;
{
var x = 2;
console.log(x); // 2
}
console.log(x); // 2
}
//var没有块{}的概念,两次输出都是第二次的定义
function letTest() {
let x = 1;
{
let x = 2;
console.log(x); // 2
}
console.log(x); // 1
}
//两次输出的不是同一个x
同一个变量只能用一种方式声明,否则会报错
var a = 1;
let b = 2;
let a = 'a'; // 报错 注:是上面 var a = 1; 那行报错
var b = 'b'; // 报错:本行报错
2. 重复声明
let
在同一个作用域中不能重复声明
var
可以重复声明,新的声明会覆盖上次声明
function f(){
let a-1;
var b=1;
let a=2;//报错
var b=2;
console.log(b);//2
}
3. 变量提升
在代码执行之前,会先扫描所有域内的var声明的变量,将其先进行初始化为undefined,然后再执行代码,即变量提升
console.log(a);//undefined
var a=1;
临时死区
var a = 2;
function f() {
console.log(a);
let a = 5;
}
f();
如果let没有变量提升,输出应该是2,但出现ReferenceError报错
在代码执行之前的扫描,同样也会对let变量进行“提升”,但并没有将其置为undefined,如果在赋值前访问的话,会出现ReferenceError错误
程序运行开始扫描,let声明 到 变量开始被赋值可被访问之间的一段时间,称为TDZ(临时死区),不可被访问
所以从进入函数 f() 开始,到let a=5
都是a变量的临死性死区,无法访问该变量