瀏覽器的預解析過程
阿新 • • 發佈:2017-12-12
優先級 為什麽 pre 後處理 來看 comm sdn data body
瀏覽器的預解析過程
題目:
var foo;
function foo(){}
console.log(foo);
- 1
- 2
- 3
- 4
結果是函數體function foo(){}
接著下面一道題:
function foo(){}
var foo;
console.log(foo);
- 1
- 2
- 3
結果也是函數體function foo(){}
所有就有很多人說,函數聲明的優先級大於變量聲明的優先級。那麽,為什麽呢?這就要從瀏覽器的預解析說起了。
預解析流程
- 搜尋預解析關鍵字
- 尋找var關鍵字
- 尋找function關鍵字
- 執行預解析
- 先應用var關鍵字聲明的標識符,使這些標識符有定義
- 標識符有定以後,使用這項標識符就不會報錯了
- 但因為沒有賦值,因此其值為undefined
- 至此標識符中保存了函數的引用
- 先應用var關鍵字聲明的標識符,使這些標識符有定義
幾個需要註意的細節
- var 關鍵字對同一個標識符重復使用時,除第一次有效外,其他均做忽略處理。
- 預解析時先處理變量聲明,再處理函數聲明
- 不要糾結誰的優先級高,這些只是表面現象
- 懂得了預解析流程,一切都是浮雲
看了預解析原理以後,下面咱們回到本文開頭的兩題,分析下預解析的過程,詳細的了解為什麽函數的優先級高於變量的優先級。follow me—->
先看第一個
var foo;
function foo(){}
console.log(foo);
- 1
- 2
- 3
預解析過程為:
var foo;<----變量聲明的var
var foo;<----函數聲明抽出的var
foo=function (){}<----函數聲明抽出的賦值
console.log(foo);
- 1
- 2
- 3
- 4
再來看第二個,
function foo(){}
var foo;
console.log(foo);
- 1
- 2
- 3
預解析過程為:
var foo;<----變量聲明的var
var foo;<----函數聲明抽出的var
foo=function (){}<----函數聲明抽出的賦值
console.log(foo);
- 1
- 2
- 3
- 4
比較這兩個,你發現了什麽?原來他們的預解析過程一樣啊,這也就是為什麽函數優先級高於變量的原因了。
如果你理解了上面的內容,那麽下面再出一個題:
var a=1;
function a(){}
console.log(a);
- 1
- 2
- 3
這個瀏覽器是如何解析的呢?下面來跟著我的思路一起走:
1. 解析器首先搜尋var 關鍵字,結果第一行就發現了,把它提取到開頭。
2. 解析器搜尋function關鍵字,第二行發現了,首先分離var+函數名,此時發現和第一步的一樣,不做處理,然後開始分離函數的賦值,也就是a=function (){}
,此時a為函數體。
3. 解析器接著處理變量的賦值,a=1
,上一步的函數體被覆蓋掉,此時a=1。
4. 最後處理console.log(a)
,自然而然的結果為1。
下面是解析器處理的代碼過程:
var a;<----變量聲明的var
var a;<----函數聲明抽出的var
a=function (){}<----函數聲明抽出的賦值
a=1;
console.log(a);
- 1
- 2
- 3
- 4
- 5
瀏覽器的預解析過程