在調用一個JavaScript方法之前,都會對方法進行一次詞法分析的過程,主要分析如下內容:
第一步: 先分析參數
第二布: 再分析變數聲明
第三步: 最後分析函式宣告
現提供一個具體例子代碼,並解析分析步驟:
function t(age){var e = 2;var age = 10;function age() {}}t(2);
具體步驟:
1、 函數在運行前的瞬間,會產生一個使用中的物件(Active Object),簡稱AO。
2、分析函數的參數,並將其作為AO的屬性,預設值全部為underfined,如:
AO{age=underfined}。
3、分析函數接受到的參數,並將參數內容設定到對象的AO屬性上,如:
AO{age=2}
4、分析函數內部的變數聲明,如var age,如果AO上還沒有age屬性,則添加AO屬性,值是undefined;如果AO上已經有age屬性則不做任何影響。如:
AO{age=2, e=undefined}
5、分析函式宣告,並將函數賦給成AO的屬性。
AO{age= function(){}, e=undefined}
注意:由於age屬性已經存在,則被覆蓋掉了。
根據以上步驟再來分析一個比較複雜的函數:
function a(b){alert(b);function b() {alert(b);}b();}a(1);
詞法分析過程:
1、分析函數的參數,結果為:AO{b=undefined}
2、分析函數的接受到的參數,結果為:AO{b=1}
3、分析函數內部的變數聲明,這裡沒有聲明內部變數。
4、分析函式宣告,結果為:AO{b=function(){alert(b)}}
詞法分析完成之後將根據這個AO對象來運行,此時2個alert(b)都將會列印b函數。
根據這個詞法的分析過程,可以清楚的明白JavaScript的運行原理,對這種奇葩的結果就自然而然的明白了。
注意點:
1、在詞法分析過程中,分析函式宣告的時候如果遇到如下情況需要注意。
function a(b){alert(b);b = function() {alert(b);}b();}a(1);
這裡的b= function(){} 並不是函式宣告,而是函數運算式的賦值,在詞法分析階段不會使b=function(){},而是在運行階段賦值。
因此這裡的結果跟上面就不一樣了,大家可以自行查看。