JS中的预解析和变量提升

492 阅读1分钟

JS中的预解析和变量提升

预解析

JS代码是由浏览器中的JavaScript解析器执行的。在JavaScript解析器执行时分为两个过程:

  • 预解析过程
  • 代码执行过程

预解析过程

  1. 把变量的声明提升到当前作用域的最前面。只会提升声明,不会提升赋值
  2. 把函数的声明提升到当前作用域的最前面。只会提升声明,不会提升赋值

注:let定义的变量,没有变量提升。因此不会被预解析。

<script>
    var a = 123
    function fn(){
        let b =234
    }
    var c = '嘻嘻嘻'
    /*
    预解析过程:
    1.现将定义的变量提升到当前作用域的最前面,进行声明
      var a
      var c
    2.将function提升到当前作用域的最前面
      function fn
    预解析完闭后,在执行代码
    */
</script>

变量提升

  • 变量提升:定义变量的时候,变量的声明会被提升到作用域的最上面,变量的赋值不会提升
<script>
    //事例一:
    console.log(a) //undefined
    var a = 1
    /*
    上述代码经过变量提升相当于
    var a
    console.log(a) // undefined
    a=1
    */
    
    //事例二:
    num = 6
    num++
    var num
    console.log(num) // 7
    /*
    变量提升会将声明提升到当前作用域的最前面
    var num 
    num = 6
    num++
    console.log(num) //7
    */
</script>
  • 函数提升:JS解析器首先会把当前作用域的函数声明提前到整个作用域的最前面

🌟函数提升的优先级大于变量提升

<script>
    console.log(fn); //fn(){}
    console.log(fn());// undefined
    var fn = 2
    function fn(){ 
        console.log(a);//undefined
        var a = 1
        console.log(a);//1
    }
</script>

因为函数提升的优先级高于变量提升首先输出的fn是一个函数体,之后在第二个log中调用了fn,再次进行预解析 将var a提升到函数作用域的最上方,则第一个a输出undefined,第二个a输出1。又因为函数没有return默认返回undefined,则log(fn())输出undefined

🌟注:函数提升只会提升函数声明式写法,函数表达式写法不存在变量提升。