前言
在JavaScript中,
let
和var
都是用来声明变量的关键字
let 和 var 的区别
作用域:
var
声明的变量具有函数作用域(function scope)。如果在一个函数内部声明,它只在该函数内部可见。如果在一个函数外部声明,它会成为全局变量。let
声明的变量具有块级作用域block scope)。这意味着let
变量只在声明它的代码块(如if
语句、for
循环等)中可见。
提升:
var
声明的变量会经历变量提升(hoisting),这意味着变量可以在声明之前使用,但会初始化为undefined
。le
声明的变量也会被升,但是不会被初始化,所以在声明之前访问它会导致ReferenceError
。
重复声明:
- 使用
var
可以在同一个作用域内多次声明同一个变量,后面的声明会覆盖前面的值。 - 使用
let
在同一个作用域内不能重复声明同一个变量,尝试这样做会导致语法错误。
全局对象属性:
- 当使用
var
在全局作用域下声明变量时,它会成为一个全局对象的属性(在浏览器中是window
对象)。 - 使用
let
在全局作用域下声明变量时,它不会成为全局对象的属性。
暂时性死区:
let
声明的变量存在暂时性死区(Temporal Dead Zone, TDZ),即在声明之前到声明的位置之间,变量是不可见的。var
没有暂时性死区,变量在声明之前就可访问,只是值undefined
。
// 全局作用域
var a //在全局作用域声明一个a变量
a = 5//变量赋值
c //变量声明必须加上关键词let var const(常量),没有就报错
d = 6//变量赋值会先查找(查找到window)如果没有,就声明(相当于使用var,但是不会预解析)再赋值
function fn() {var b=6//私有作用域声明一个变量console.log(a)//变量使用,在自己作用域查找,没有去上一级查找(作用域链),找到了a为5返回5
}
fn()
console.log(b)//错误全局中没有b变量,b变量是定义在function里面的,是fn私有的,全局调用报错
块级作用域和局部作用域区别
块级作用域:只要{}没有和函数结合在一起, 那么应该"块级作用域"
局部作用域:函数后面{}中的的作用域, 我们称之为"局部作用域"
1、在块级作用域中通过var定义的变量是全局变量
2、在局部作用域中通过var定义的变量是局部变量
3、let只要在{}里面就是局部变量
4、无论是在块级作用域还是在局部作用域, 省略变量前面的let或者var就会变成一个全局变量(省略之后,赋值号必须要,不然报错表示直接使用not defined,省略之后不会进行预解析,相当于给window增加了一个属性名和属性值)
//块级作用域{}
{var a = 1; // 全局变量let b = 2; // 局部变量c = 3; // 全局变量
}//函数后的{} 局部作用域
function test() {console.log(d)//undefinedvar d = 4; // 局部变量let e = 5; // 局部变量console.log(f)//报错(Uncaught ReferenceError: f is not defined)f = 6; // 全局变量 不会预解析console.log(f)//6 赋值了
}
console.log(a)//打印1
console.log(b)//报错
console.log(c)//打印3
test()//执行函数test,里面的变量才会预解析,将de解析为局部变量,f为全局变量,(变量污染,里面的变量会污染全局),不执行f变量会出错
console.log(d)//报错
console.log(e)//报错
console.log(f)//打印6