一、var和let声明的变量所属作用域不同
var声明的变量属于函数作用域,而let声明的变量属于块级作用域
二、var和let声明的变量所属作用域不同,相应的变量提升也不同
var声明的变量
在函数作用域中,var声明的变量只存在变量提升,不存在变量初始化提升
function fn() {
console.log(name); //undefined,说明存在变量提升,不存在变量初始化提升
var name=1
}
fn()
在全局作用域或者块级作用域中,var声明的变量存在变量提升和存在变量初始化提升
{
console.log(name); //1,说明存在变量提升,存在变量初始化提升
var name=1
}
let声明的变量
let声明的变量在任何作用域中都只存在 变量提升,不存在变量初始化提升
函数作用域中
function fn(){
console.log(name); //报错,'name' before initialization,说明其实存在变量提升,但是没有进行初始化
let name=1
}
fn()
块级作用域中
{
console.log(name); //报错,'name' before initialization,说明其实存在变量提升,但是没有进行初始化
let name=1
}
三、对暂时性死区(TDZ)的理解
一个作用域内如果存在let,const声明的变量,那么从该作用域开始到let,const声明的变量的地方会产生一个暂时性死区区域,在这个暂时性死区区域无法访问到let,const声明的变量
{ // 块级作用域开始,TDZ开始
console.log(temp) // TDZ区域访问变量,报错,Cannot access 'temp' before initialization
let temp // 遇到let变量声明,TDZ结束
console.log(temp) // undefined,变量声明但未赋值
// 赋值
temp = 345
console.log(temp) // 345
// 块级作用域结束
}
//在块级作用域外访问
console.log(temp) // ReferenceError: temp is not defined,无法访问
四、总结
1、我们要逐渐放弃var声明语法,改用let,const声明的语法
2、变量必须声明后再进行访问(解决暂时性死区问题)