python學習之路 jJavaScript詞法分析
詞法分析步驟
JavaScript在運行前會有一個類似預編譯的過程這個過程就是我們所說的詞法分析。這個詞法分析的步驟
- 分析參數
- 再分析變量的聲明
- 分析函數說明
列子:
function func(age){
console.log(age); //f age(){}
var age = 27;
console.log(age); //27
function age(){}
console.log(age); //27
}
func(3)
JavaScript運行的時候遇到函數,會生成一個活動對象(Active Object),後面簡稱AO
第一步 分析形式參數:
當函數有形式參數的時候就會把實現 AO.age = undefined
當我們傳入實參的時候就會把前面的覆蓋 AO.age = 3;
第二步 分析局部變量
找到所有的局部變量然後從上到下一步一步的分析。
上面列子的var age = 27 開始因為詞法分析所以把AO.age = undefined
所以幾乎所有的局部變量都是AO.age = undefined形式。
所以AO.age = undefined
因為形式參數優先於局部變量,上面傳入實參後AO.age = 3所以在這裏AO裏面的age屬性值就是AO.age = 3
在這裏要註意到形式參數的值在詞法分析的時候優先於局部變量在這裏AO裏面的屬性
第三步 分析函數聲明表達式
當所有的局部變量分析完後我們開始分析函數聲明表達式
上面的函數就會實現 AO.age = function()
又是因為上面有同樣的屬性所以就會覆蓋上面的AO.age = undefined
所以最後AO.age = f age(){}
註意:上面函數聲明表達式級別最高會覆蓋前面相同的屬性,然而局部變量和形式參數互不影響。
當我們調用函數的時候:
上面的這些詞法分析做完以後得到AO.age = f age(){},
調用函數我們開始運行到第一行代碼,讓我們打印,所以第一個打印的就是 f age(){}
運行到var age = 27的時候這裏age的值就是27.
在接下來我們要打印age的值所以第二個打印為 27
再到下面一行是一個函數表達式但是這個表達式沒有運行所以不影響局部變量age的值這是age還是27。
所以第三個打印的還是27
這個就是上面函數從開始的詞法分析,到最後的函數運行,再到後面的函數運行結果。
下面是一個代碼會解釋上面的
<script> function func(age){ console.log(age); //3 var age = 27; console.log(age); //27 } func(3) //在這我們可以看詞法分析後的age=3也就是說形式參數優先於局部變量。 </script> <script> function func(age){ console.log(age); //f age(){} var age = 27; console.log(age); //27 function age(){} console.log(age); //27 var age = 66 } func(3) //上面我們可以看到當我們的局部變量在函數聲明表達式後面的時候不 //會改變這個屬性的值所以說函數聲明表達式級別最高有他就會覆蓋前面的 </script> <script> function func(){ console.log(age); //undefined var age = 27; console.log(age); //27 } func() //上面再進行詞法分析的時候沒有形式參數沒有函數聲明表達式所以最後得到的age=undefined </script>
示列1
<script> function func(age) { var age; console.log(age); //f age(){} var age = 23; console.log(age); //23 function age() {} console.log(age); //23 } func(28) </script>
開始詞法分析
1、形式參數
開始 AO.age=undefined
傳入實參後得到AO.age = 28
2、局部參數
因為有形式參數,所以這裏的局部參數AO.age不發生改變。到這裏A.age=28
3、函數聲明表達式
這裏可以得到AO.age=f age(){}
由於他的級別最高。所以詞法分析後得到AO.age = f age(){}
函數調用執行階段
執行到第一個log的時候:由於前面沒有局部變量的賦值所以這個打印的就是開始的詞法分析中變量的值: f age(){}
當執行到第二個log的時候:由於前面局部變量賦值所以會覆蓋詞法分析中的變量的值所以輸出為 23
當執行到第三個log的時候:前面沒有執行任何代碼所以得到輸出的值為23。
示列2
<script> function func(age) { var age; console.log(age); // f age() {console.log(age); } var age = 23; console.log(age); // 23 function age() { console.log(age) } age(); //報錯說這個函數沒定義 console.log(age); // } func(22) </script>
詞法分析
這裏就不詳細分析了最後可以得到AO.age = f age(){}
執行階段分析
var age: 這個只是聲明下局部變量對我們詞法分析的不影響這裏age = f age(){console.log(age)}
console.log(age):所以直接打印f age(){}
var age = 23: 所以就會覆蓋詞法分析的age 所以這裏的var age = 23;
console.log(age):由上面知道age = 23所以這裏打印的是23
這一行是一個函數所以不執行,
age(): 由於前面我們定義了age為局部變量並且為他賦值了所以會報錯說這不是一個函數
console.log(age):由上面知道var age = 23所以這裏打印的是23
上面我們可以知道當我們定義函數的時候,在函數的前面如果聲明一個和函數名一樣的變量並且賦值,要不覆蓋。我們可以這樣理解一個JavaScript代碼就是一個詞法分析。當我們執行的時候在函數前面有一個一樣的變量賦值那麽我們在詞法分析得到的這個函數對象就會被我們變量賦值所覆蓋。因為執行的時候我們的函數是不執行的,只有在調用的時候才會執行。
<script> console.log(func); //f func(age) {var age;console.log(age);var age = 23;console.log(age);} var func=22; console.log(func); //22 function func(age) {var age;console.log(age);var age = 23;console.log(age);console.log(age);} func(22) //報錯說沒有這個函數因為上面覆蓋了。 </script> <script> console.log(func); //f func(age) {var age;console.log(age);var age = 23;console.log(age);console.log(age);} function func(age) { var age; console.log(age); // f age() {} 這個來自於詞法分析 var age = 23; function age() {} //不執行 console.log(age); // 23 } func(22) //這個就沒有報錯,因為上面沒有所得到的詞法分析沒有被覆蓋。 </script>
上面就是關於JavaScript的一些詞法分析就是在執行代碼的時候他會提前進行詞法分析。上面是我個人學道德有些地方有可能說的不是很明白。沒辦法水平有限
python學習之路 jJavaScript詞法分析