关于var、let、const对于变量声明的理解
首先抛出几个例子思考一下
1. function foo () {
console.log(a) // Uncaught ReferenceError: a is not defined
}
foo()
2. let a = 1;
function foo () {
console.log(a) // 1
}
foo()
3. let a = 1;
function foo () {
let a = 2 或者 var a = 2 或者 const a = 2
console.log(a) // 2
}
foo()
对比1、2、3不难发现在块级环境中,优先查找当前块中通过var、let或者const定义的变,如果有则保留当前值;否则将向块级的外层逐层查找,直至查找到最外层(window)块级环境,有则用,没有则抛出ReferenceError
4. let a = 1
function foo () {
let a = 2
let a = 3
console.log(a) // Uncaught SyntaxError: Identifier 'a' has already been declared
}
foo()
5. let a = 1
function foo () {
var a = 2 // const a = 2
let a = 3
console.log(a) // Uncaught SyntaxError: Identifier 'a' has already been declared
}
foo()
6. let a = 1
function foo () {
var a = 2
var a = 3
console.log(a) // 3
}
foo()
对比4、5、6则可见,同一块级环境中由let和const创建的变量不能重复声明,而由var创建的重复变量,之前声明的则会被最后声明的覆盖
7. let a = 1
function foo () {
console.log(a) // undefined
var a = 2
console.log(a) // 2
}
foo()
8. let a = 1
function foo () {
console.log(a) // Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 2 或者 const a = 2
console.log(a)
}
foo()
对比7、8则发现通过 var 声明的变量有初始值 undefined,而通过 let 声明的变量直到定义的代码被执行时才会初始化。在变量初始化前访问变量会导致 ReferenceError
综上总结
在js中变量提升指的是在声明变量的代码执行之前,可以进行初始化和使用;而不是指:在创建词法环境阶段是否会创建对应的标识符。
通过 var 声明的变量和 let 或 const 声明的变量,在创建相应作用域的词法环境阶段,都会注册标识符,但仅通过 var 声明的变量存在会变量提升,若在通过 let 或 const 声明了变量的(块)作用域中,先使用再声明该变量,就会抛出错误:ReferenceError

浙公网安备 33010602011771号