預編譯的兩種情況 全局: 1.全局 直接是script標簽中的代碼,不包括函數執行 執行前: 1.首先生成一個GO(global object)對象,看不到,但是可以模擬出來用來分析 2.分析變數聲明,變數名為屬性名,值為undefined 3.分析函數聲明,函數名為屬性名,值為函數體,如果函數名和 ...
預編譯的兩種情況
全局:
1.全局 直接是script標簽中的代碼,不包括函數執行
執行前:
1.首先生成一個GO(global object)對象,看不到,但是可以模擬出來用來分析
2.分析變數聲明,變數名為屬性名,值為undefined
3.分析函數聲明,函數名為屬性名,值為函數體,如果函數名和變數名相同,則無情覆蓋
函數內部:
1.函數調用,也是會生成自己的作用域(AO:active object),AO活動對象. 函數調用時候,執行前的一瞬間產生的,如果有多個函數的調用,會產生多個AO
1.1 函數執行前的一瞬間,生成AO活動對象
1.2 分析參數,形參作為對象的屬性名,實參作為對象的屬性值
1.3 分析變數聲明,變數名為屬性名,值為undefined,如果遇到AO對象上屬性同名,不去做任何改變
1.4 分析<b>函數聲明</b>,函數名為屬性名,值為函數體,如果遇到AO對象上屬性同名,則無情覆蓋
2.逐行執行
舉例時間:
簡單版本-全局:
<script type="text/javascript">
console.log(a);//a函數函數體
var a=10;
function a(){
}
</script>
1.首先生成一個GO(global object)對象,看不到,但是可以模擬出來用來分析
GO{
}
2.分析變數聲明,變數名為屬性名,值為undefined
GO{
a:underfined
}
3.分析函數聲明,函數名為屬性名,值為函數體,如果函數名和變數名相同,則無情覆蓋
GO{
a:function a(){
}
}
接下來就是執行代碼,console.log輸出a函數的函數體
簡單版本-局部1:
<script type="text/javascript"> function fun(test){ console.log(test);//5 var test = 10; console.log(test);//10 } fun(5); </script>
1.函數執行前的一瞬間,生成AO活動對象
AO{
}
2.分析參數,形參作為對象的屬性名,實參作為對象的屬性值
AO{
test:5;
}
3. 分析變數聲明,變數名為屬性名,值為undefined,如果遇到AO對象上屬性同名,不去做任何改變
AO{
test:5;
}
接下來執行代碼,第一個console.log輸出AO里test的值,
第二個console.log輸出上面一行賦值為10過後的值,為10
簡單版本-局部2:
<script type="text/javascript"> function fun(test){ console.log(test);//test函數體 var test = 10;//給test賦值為10 function test(){//聲明函數 } console.log(test);//10 } fun(5); </script>
1.函數執行前的一瞬間,生成AO活動對象
AO{
}
2.分析參數,形參作為對象的屬性名,實參作為對象的屬性值
AO{
test:5;
}
3. 分析變數聲明,變數名為屬性名,值為undefined,如果遇到AO對象上屬性同名,不去做任何改變
AO{
test:5;
}
4. 分析函數聲明,函數名為屬性名,值為函數體,如果遇到AO對象上屬性同名,則無情覆蓋
AO{
test:function(){};
}
5.逐行執行
然後開始一行一行執行代碼,第一個console.log輸出的結果是test的函數體
下一行就是給test賦值為5,
下一行就是函數體的聲明,不做處理
下一行就是console.log輸出的結果就是10
複雜版本:
1 <script type="text/javascript"> 2 console.log(test); 3 function test(test){ 4 console.log(test); 5 var test = 123; 6 console.log(test); 7 function test(){ 8 9 } 10 console.log(test); 11 var test = function(){} 12 console.log(test); 13 } 14 test(10); 15 var test = 456 16 console.log(test); 17 </script>
預編譯開始,先生成一個GO{
}
1.看變數GO{
test:underfined
}
2.看函數聲明GO{
test:function test(test){
console.log(test);
var test = 123;
console.log(test);
function test(){
}
console.log(test);
var test = function(){}
console.log(test);
}
}
把整個函數體給test
預編譯完成,開始執行代碼,第二行的結果是test函數的函數體
3到13行都是函數聲明,不用管
第14行函數執行,傳入參數10
函數執行的時候產生AO{
}
1.看參數AO{
test:10
}
2.看變數,變數同名,不用管變數AO{
test:10
}
3.看函數,函數和參數同名,函數把參數覆蓋AO{
test:function test(){}
}
4.逐行執行
第三行列印名字為test的函數體,
第四行給test賦值123,第五行列印123
7到9行函數體聲明不用管
第十行列印123
第十一行把一個匿名函數(沒有函數名的函數)賦值給test
第十二行函數執行完畢
第十四行回到全局,把456賦值給test
第十五行列印456
效果圖: