var与let
JavaScript中声明变量通常使用var
,ES6中引入了let
声明变量,这两者有什么区别呢?
1. 作用域
- 通过
var
定义的变量,作用域是整个封闭函数,是全域的 。 - 通过
let
定义的变量,作用域是在块级或是子块中。
|
|
2. 不可以在当前作用域重复声明同一个变量
在同一个函数或同一个作用域中用let
重复定义一个变量将引起 TypeError
3. 变量提升
var
声明的变量由于存在变量提升(hoist),不论var
声明的变量处于当前作用域的第几行,都会提升到作用域的头部。
浏览器在运行代码之前会进行预解析,首先解析函数声明,定义变量,解析完之后再对函数、变量进行运行、赋值等。
那么let
存在变量提升么?
let
是存在变量提升的,在JavaScript中,所有的声明(var
、function
、let
、const
、class
、function\*
)都会存在变量提升,var
声明的变量与let
声明的变量区别在于初始化值的不同。
var
声明的变量会被提升到作用域的顶部并初始化为undefined
,而let
声明的变量在作用域的顶部未被初始化,直到let
声明的语句被赋值,因此当使用这个值的时候会导致一个reference error
的错误,在let
声明变量之前被称为temporal dead zone
,即临时死亡区。
4. let
与for
循环配合
|
|
此时打印出的结果为0 1 2 3 4 ,let
与for
循环使用时,其作用域是(let i = 0; i < 5 ; i++ )
,但是ECMAScript规定,会在{}块级作用域中定义一个let j
临时变量与(let i = 0; i < 5 ; i++ )
中的i
相等,因此setTimeout
中的i
指向不同的i
。
而如果换成var
之后, 由于i
是函数级变量,5个内部函数都指向了同一个i
,而i
最后一次赋值是5,因此打印出是5个5。
参考: