淺談JS預解析

Gudeki發表於2020-11-28

預解析

就是 js 程式碼的執行過程

什麼是預解析

  1. 預: 在所有 js 程式碼執行之前
  2. 解析: 對整篇 js 程式碼進行通讀並解釋(瀏覽器在解析)

1.解析了什麼內容(只有兩種內容)

  1. var 宣告的變數
    var num
  2. 宣告式函式(不是賦值式函式)
    function fn() {}

2.怎麼解析的

  1. var 宣告的變數
    在所有 js 程式碼執行之前, 先把變數宣告好
    再開始執行程式碼

  2. 宣告式函式
    在所有 js 程式碼執行之前, 先把函式名宣告好, 並且給這個函式名賦值為一個函式
    再開始執行程式碼

3.var 的預解析

var num = 100
這一行程式碼包含了兩個操作
1. 宣告變數 var num
2. 變數賦值 num = 100
在這兩個操作裡面
宣告變數那一步是在 預解析 的時候就完成的
在所有 js 程式碼開始執行之前, 就已經做好了
變數賦值那一步是在 真正執行程式碼 的時候才開始做的

    var num = 100
    console.log(num)
    // 在 JS 執行的時候
    // 先進行預解析
    // var num
    // 不在有別的東西可以解析了, 那麼開始執行程式碼
    // num = 100
    // console.log(num)// 給num賦值為 100 ,就是 100


    console.log(num)
    var num = 100
    console.log(num)

    /*
      拆解程式碼的執行過程
        console.log(num)
        var num = 100

      1. 預解析的過程
        var num

      2. 真正執行 所有的 JS 程式碼
        console.log(num) // 其實就是有這個變數,
         但是還沒有賦值, 列印結果就是 undefined
        num = 100
        console.log(num)// 給num賦值為 100 ,列印結果就是 100
    */

4.宣告式函式預解析

function fn() {}
解析一下這一行程式碼

  1. 預解析的過程
    告訴瀏覽器, fn 是一個可以使用的名字
    並且 fn 這個名字是一個函式,給這個函式名賦值為一個函式

  2. 真正的程式碼開始執行

    fn()
    function fn() {
      console.log('我是 fn 函式')
    }

    /*
      程式碼的執行
        fn()
        function fn() {
          console.log('我是 fn 函式')
        }

      1. 預解析
        告訴瀏覽器 fn 這個名字被宣告過可以使用
        並且 fn 還是一個函式 function fn() { console.log('我是 fn 函式') }

      2. 執行程式碼
        fn()
    */

5.賦值式函式的預解析

賦值式函式不會按照宣告式函式的預解析進行
而是按照 var 的預解析規則進行
var fn = function () {}

  fn() // fn is not a function
  var fn = function () {
    console.log('我是 fn 函式')
  }

  /*
    分析程式碼執行過程
    fn()
    var fn = function () {}

    1. 進行預解析
      var fn
      就告訴瀏覽器這個 fn 被聲名過了, 但是並沒有給他賦值為一個函式

    2. 程式碼開始執行
      fn() // 這行程式碼執行的時候, fn 還是一個沒被賦值的狀態, 是個 undefined
      fn = function () {}
  */
  

6.預解析的無節操

  1. 不管 if 條件是不是成立, 寫在 {} 裡面的程式碼都會進行預解析
    只是條件不成立的時候, 不會執行 {} 裡面的賦值操作
  // 預解析的無節操 - 1
    console.log(age) // undefined

    if (2 < 1) {
      var age = 18
    }

    console.log(age) // undefined

    /*
      解析程式碼執行過程
      console.log(age) // undefined
      if (2 < 1) {
        var age = 18
      }
      console.log(age) // undefined

      1. 預解析 - 不管 if 是否成立 age都會進行預解析
        var age

      2. 程式碼執行
        console.log(age) // 沒有進行賦值, 就是 undefined
        if (2 < 1) {
          age = 18
        }
        console.log(age) // 因為 if 條件為 false, 所以 {} 裡面的程式碼沒有執行
    */   


  1. 當再函式內部的時候, return 後面的程式碼雖然不會執行
    但是會進行預解析
// 預解析的無節操 - 2
    function fn() {
      console.log(num) // undefined


      return
      var num = 100
    }

    fn()

        /*
      解析程式碼執行過程

      1. 預解析 - 不管 teturn 後面程式碼會不會執行,num都會進行預解析
          fn=function () {
              console.log(num)
              return
              var num = 100
              }
          var num

          

      2. 程式碼執行
      fn()
      console.log(num) 
    */

相關文章