关于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

posted @ 2019-10-18 17:03  zmLove  阅读(478)  评论(0)    收藏  举报