*函式預編譯相關[JavaScript_005]
JavaScript一些特點
- 單執行緒執行
- 解釋性語言,解釋一行執行一行
預編譯
作用:可以進行初始化相關操作
原則(現象):函式宣告整體提升; 變數宣告提升;
解釋1:函式宣告整體提升
test();//此時呼叫結果仍舊可以輸出hello function test(){ console.log('hello'); }
原因:函式宣告時會提升自己的位置,置於Js指令碼頂部
解釋2:變數宣告提升
var a ; console.log(a);//此時結果為undefined a = 'hello';
console.log(a);//此時結果為undefined var a = 'hello';
原因:變數宣告時會提升自己的位置,第二個指令碼的宣告和賦值操作在一起,所以可以看作指令碼一的效果一致,將指令碼二的宣告放置頂部。
預編譯前奏
imply gobal(暗示全域性變數)
在變數未經過宣告,直接進行賦值
a = 10; console.log(a);//此時輸出仍為10,但是此時的a為window.a,其中window為全域性的域
function test(){ var a = b =159;//其中b未宣告,為window域所有 } //輸出window.a =undefined; //輸出window.b =159;
預編譯詳解(函式AO)
-
步驟
- 建立AO (Activation Object)活躍物件 ,也是執行期上下文
- 找形參和變數宣告,將變數和形參名作為AO屬性名,值為undefined
- 將實參與形參統一
- 函式體的函式宣告,注意不是函式表示式
function fn(a){ console.log(a);//輸出結果為function a(){} var a =123; console.log(a);//輸出結果為123 function a(){}; console.log(a);//輸出結果為123 var b = function(){} console.log(b);//輸出結果為function(){} function d(){}; } fn(1);
關注AO物件預編譯的過程
階段1
建立AO物件
階段2
變數 | 值 | 原因 |
---|---|---|
a | undefined | 初始化 |
b | undefined | 初始化 |
階段3
變數 | 值 | 原因 |
---|---|---|
a | 1 | 實參與形參統一 |
b | undefined | 不變 |
階段4
變數 | 值 | 原因 |
---|---|---|
a | function a(){} | 函式宣告 |
b | undefined | 不變 |
d | function d(){} | 函式宣告 |
預編譯詳解(全域性GO)
-
步驟
- 建立GO (Global Object)全域性物件 ,可以理解為window === GO
- 函式體的函式宣告,注意不是函式表示式
預編譯詳解(混合GO+AO)
- 預編譯順序:先生成GO物件,在執行方法前生成AO物件;
- 訪問關係:先訪問AO,若不存在則訪問GO;(鏈式關係 )
- 練習1
gobal = 100; function fn(){ console.log(gobal);//undefined gobal = 200; console.log(gobal);//200 var gobal = 300; } fn(); var global;
- 練習2
function tests(){ console.log(b);//undefined(並不會報錯,預編譯時不考慮if) if(a){ var b = 100; } console.log(b); c = 234; console.log(c);//234(為GO.c) } var a; test(); a = 10; console.log(c);//234
- 練習3
a = 100; function demo(e){ function e(){};//undefined arguments[0] = 2; console.log(e);//2 if(a){ var b =123; function c() { } } var c; a = 10; var a; console.log(b);//undefined f = 123; console.log(c);//undefined(function c(){}) console.log(a);//10 } var a; demo(1); console.log(a);//100 console.log(f);//123