什麼是JavaScript 預解析

這是我參與8月更文挑戰的第10天,活動詳情查看:8月更文挑戰瀏覽器

JavaScript 代碼的執行是由瀏覽器中的 JavaScript 解析器來執行的。JavaScript 解析器執行JavaScript 代碼的時候,分爲兩個過程:預解析過程和代碼執行過程markdown

預解析過程

預解析過程:app

  1. 把變量的聲明提高到當前做用域的最前面,只會提高聲明,不會提高賦值。函數

  2. 把函數的聲明提高到當前做用域的最前面,只會提高聲明,不會提高調用。post

  3. 先提高 var,再提高 function。ui

變量聲明提高

在預解析過程當中,全部定義的變量,都會將聲明的過程提高到所在的做用域最上面,在未來的代碼執行過程當中,按照前後順序會先執行被提高的聲明變量過程。url

提高過程當中,只提高聲明過程,不提高變量賦值,至關於變量定義未賦值,變量內存儲 undefined 值spa

所以,在 js 中會出現一種現象,在前面調用後定義的變量,不會報錯,只會使用 undefined 值。3d

函數聲明提高

在預解析過程當中,全部定義的函數,都會將聲明的過程提高到所在的做用域最上面,在未來的代碼執行過程當中,按照前後順序會先執行被提高的函數聲明過程。code

在預解析以後的代碼執行過程當中,函數定義過程已經在最開始就會執行,一旦函數定義成功,後續就能夠直接調用函數。

所以,在 js 中會出現一種現象,在前面調用後定義的函數,不會報錯,並且能正常執行函數內部的代碼

函數聲明提高能夠用於調整代碼的順序,將大段的定義過程放到代碼最後,可是不影響代碼執行效果。

console.log(a);
        console.log(fun)

        function fun(){
            console.log(2);
        }

        var a=1;
        console.log(a);
複製代碼

image.png

提高順序

預解析過程當中,先提高 var 變量聲明,再提高 function 函數聲明

假設出現變量名和函數名相同,那麼後提高的函數名標識符會覆蓋先提高的變量名,那麼在後續代碼中出現調用標識符時,內部是函數的定義過程,而不是 undefined

若是調用標識符的過程在源代碼函數和變量定義後面,至關於函數名覆蓋了一次變量名,結果在執行到變量賦值時,又被新值覆蓋了函數的值,那麼在後面再次調用標識符,用的就是變量存的新值。

建議:不要書寫相同的標識符給變量名或函數名,避免出現覆蓋。

console.log(fun);

        var fun;

        function fun(){
            console.log(2);
        }

        console.log(fun);  //能夠看到既有變量又有函數時, 最後輸出fun是什麼

        fun = "hello";  //字符串不能傳給函數, 因此後面一行調用函數時會報錯
        fun()
複製代碼

image.png

能夠看到在上面代碼中, 既有fun變量, 又有fun函數的代碼中, 後面提高的函數會覆蓋先前提高的變量, 因此最後fun指的是函數, 再給他賦值一個字符串, 就會報錯了.

函數表達式的提高

在預解析過程當中,函數表達式進行的是變量聲明提高,而不是函數聲明提高。提高後變量內部存的是一個 undefined。在前面進行函數方法調用,數據類型會提示錯誤。

建議:定義函數時,最好使用 function 關鍵字定義方式,這樣函數聲明提高能夠永遠生效。

console.log(foo);

        var foo = function(){
            console.log(3)
        }

        console.log(foo);
        foo();
複製代碼

image.png

代碼執行過程

在預解析以後,根據新的代碼順序,從上往下按照既定規律執行 js 代碼。

相關文章
相關標籤/搜索