天天看點

聲明及指派_JavaScript-預解析和聲明提升

聲明及指派_JavaScript-預解析和聲明提升
好好學習,天天向上

一、預解析

  • JavaScript 代碼的執行是由浏覽器中的 JavaScript 解析器來執行的,JavaScript 解析器執行
  • JavaScript 代碼的時候,分為兩個過程:
    • 1.預解析過程:
      • 1. 把變量的聲明提升到目前作用域的最前面,隻會提升聲明,不會提升指派
      • 2. 把函數的聲明提升到目前作用域的最前面,隻會提升聲明,不會提升調用
      • 3. 先提升 var,再提升 function
    • 2.代碼執行過程:
      • 在預解析之後,根據新的代碼順序,從上往下按照既定規律執行 js 代碼

二、聲明提升

1、變量聲明提升

  • 在預解析過程中,所有定義的變量,都會将聲明的過程提升到所在的作用域最上面,在将來的代碼執行過程中,按照先後順序會先執行被提升的聲明變量過程
  • 提升過程中,隻提升聲明過程,不提升變量指派,相當于變量定義未指派,變量記憶體儲 undefined 值
  • 是以,在 js 中會出現一種現象,在前面調用後定義的變量,不會報錯,隻會使用 undefined 值
<script>
    // 預解析,把變量聲明部分提升到了作用域最頂部
    var a; // 相當于存了一個 undefined的值
    // 調用一個變量
    console.log(a); // undefined
    // 後定義的變量
    // var a = 1;
    a = 1
</script>
           

2、函數聲明提升

  • 在預解析過程中,所有定義的函數,都會将聲明的過程提升到所在的作用域最上面,在将來的代碼執行過程中,按照先後順序會先執行被提升的函數聲明過程
  • 在預解析之後的代碼執行過程中,函數定義過程已經在最開始就會執行,一旦函數定義成功,後續就可以直接調用函數
  • 是以,在 js 中會出現一種現象,在前面調用後定義的函數,不會報錯,而且能正常執行函數内部的代碼
<script>
    // 預解析,把函數聲明部分提升到了作用域最頂部

    // 先調用函數
    fun(); // 2
    function fun (){
        console.log(2);
    }
    fun(); // 2
</script>
           
提升順序
  • 預解析過程中,先提升 var 變量聲明,再提升 function 函數聲明
  • 假設出現變量名和函數名相同,那麼後提升的函數名辨別符會覆寫先提升的變量名,那麼在後續代碼中出現調用辨別符時,内部是函數的定義過程,而不是 undefined
  • 如果調用辨別符的過程在源代碼函數和變量定義後面,相當于函數名覆寫了一次變量名, 結果在執行到變量指派時,又被新值覆寫了函數的值,那麼在後面再次調用辨別符,用的就是變量存的新值
  • 建議:不要書寫相同的辨別符給變量名或函數名,避免出現覆寫
<script>
    console.log(fun);
    var fun = "hah";
    fun(); 
    function fun (){
        console.log(1);
    }
    fun();

    // ↑ 在預解析中 相當于 ↓

    var fun;
    console.log(fun);
    function fun (){
        console.log(1);
    }
    fun = "hah";
    fun();
    fun();
</script>
           
聲明及指派_JavaScript-預解析和聲明提升
函數表達式的提升
  • 在預解析過程中,函數表達式進行的是變量聲明提升,而不是函數聲明提升。提升後變量内部存的是一個 undefined。在前面進行函數方法調用,資料類型會提示錯誤
  • 建議:定義函數時,最好使用 function 關鍵字定義方式,這樣函數聲明提升可以永遠生效
<script>
    console.log(foo); // undefined
    foo(); // 報錯
    // 函數表達式進行的是變量聲明提升
    var foo = function (){
        console.log(1);
    };
</script>
           
函數聲明提升的應用:
  • 函數聲明提升可以用于調整代碼的順序,将大段的定義過程放到代碼最後,但是不影響代碼執行效果