浅聊一下 let,const,var

196 阅读3分钟

let const var

前言: let, const,var在我们的代码中是很常见的,但总是对它有一点模模糊糊的,像在我面前隔了一层面纱。最近看了多篇文章,小小的总结了一下,希望自己能搞懂它,也希望对各位有所帮助。(文中的例子都是经过vscode验证过的)

1. 变量提升:

1.1 作用域角度

从作用域来说,这三个都是有变量提升的。执行一段代码时,作用域是优先所有变量建立起来的,所以它在建立的时候就会看看自己内部有什么变量。

  • var :有变量提升

     ​
         console.log(aa); // undefined
         var aa = '22'
     ​
    
  • let:下面这个例子可以证明它是有变量提升的。

     let a = '1'
     {
         console.log(a); 
         //ReferenceError: Cannot access 'a' before initialization
         let a = '2'
     }
    
    let a = 1
    {
    console.log(a); //1
    }
    

    如果let没有被提升的话,那么a打印出来的值应该是外部 a 的值 1 ,而这里却是报错(错误信息意思:在a没有初始化之前不能访问)。

  •  constlet一样,通过下面例子也可以说它是由变量提升的

    const b = '1'
         {
             console.log(b);
             // ReferenceError: Cannot access 'b' before initialization
             const b = '3'
         }
       

1.2 代码执行角度

从代码执行这个角度来说,let,const是没有变量提升的。就是常说的,在声明之前var可以被访问,而let,const不能。

总结下letconstvar和函数的创建过程:
    -   letconst是【创建】提升
    -   var是【创建】提升,【初始化】提升
    -   fn 是【创建】提升,【初始化】提升,【赋值】提升

下面就详细说说他们的创建过程:

  • let,const:({let a = 1})

    • 在一个作用域{}里,找到所有用let,const声明的变量,在环境中【创建】这些变量。
    • 开始执行(注意,没有初始化哦),所以引用它的时候会报错。
    • 再【初始化】为1。如果是 let a,那么就初始化为undefined。(注意这不是赋值哦)
  • var:{var a = 1}

    • 在一个作用域{}里,找到所有用var声明的变量,在环境中【创建】这些变量。(和上面一样)

    • 将这些变量【初始化】为undefined

    • 开始执行代码

    • 将 a变量 【赋值】为 1

    就是说,var会在代码执行之前就已经完成了【创建】和【初始化】这两个过程

  • fn:

    • 找到所有用function声明的变量,在环境中【创建】这些变量
    • 将这些变量【初始化】并【赋值】为 函数体
    • 开始执行

就是说,fn在代码执行之前就完成了,创建,初始化,赋值这三个步骤。所以可以在fn代码前调用它。

  fn() // hello
  function fn(){
      console.log('hello')
  }

2. 它们值能不能改变?

2.1 var

var声明的变量值是可以改变的,而且可以重复声明。后面的变量名会覆盖前面的相同变量名。

       var a = 1
       console.log(a); //1
       a = 2
       console.log(a); //2
       var a = 3
       console.log(a); //3

2.2 let

let不可以重复声明,但是可以重新赋值

      
       let a = 3
       console.log(a); //3
           a=4
       console.log(a); //4
       let a = 5
       console.log(a);
        //SyntaxError: Identifier 'a' has already been declared

2.3 const

const :不可以重复声明,简单类型的变量值不可以重新赋值,但是复杂类型(对象内的属性)内部的变量可以

      const a = 2
       console.log(a); //2
       a = 3
       console.log(a);
      //  TypeError: Assignment to constant variable.
       const a = {
           d:1,
           dd:false
       }
       console.log(a.dd); //false
       a.dd = true 
       console.log(a.dd); //true

3.扩展:为什么全局对象可以访问到var变量,却不能访问到let和const变量?

image.png

image.png

回答:

因为,var声明的对象是挂载在全局对象上的,存放在global作用域中。但是let ,const声明的变量是放在别的作用域里面的,所以 window全局对象是访问不到的。例子:

(在HTML中)
 <body>
     <script>
         var a = 12
         let aaaa = 3
         function fn(){
             
             let b = 12
             const d = 0
         
         }
         console.log(fn.prototype);
     </script>
 </body>

image.png 上面的例子显示,let声明的变量 aaa是存放在 Script作用域的。