js函式和變數的宣告與執行順序
一、函式執行順序
1、正常順序
1 function f(){ 2 alert(2); 3 } 4 f(); //alert 2
所有瀏覽器都能測試通過。
2、倒序呼叫
1 f(); //alert 2 2 function f(){ 3 alert(2); 4 }
之前一些瀏覽器會報undefined,不過,目前的版本大多都可以了
3、含參函式倒序
1 f(2); //alert 2 2 function f(a){ 3 alert(a); 4 }
目前主流瀏覽器一樣可以正常測試通過
4、宣告式函式和賦值式函式
1 f(); // 2 2 function f() { // 宣告式函式 3 console.log(2); 4 } 5 f1(); // Uncaught TypeError: f1 is not a function 6 var f1 = function () { // 賦值式函式 7 console.log(2); 8 }
宣告式函式與賦值式函式的區別在於:在JS的預編譯期,宣告式函式將會先被提取出來,然後才按順序執行js程式碼。
二、變數執行順序
1、正常順序
1 var a =2; 2 alert(a); //alert 2
2、倒序使用變數
1 alert(a); //alert undefined 2 var a =2;
在變數未定義之前使用,會返回undefined。
3、區域性變數的執行
*注意:js中全域性var宣告的為全域性變數 函式體內var宣告為區域性變數(函式外部訪問不到)但是,函式體內未用var宣告的為全域性變數(函式外部可以使用)
1 function f(){ 2 alert(a); 3 a = 3; 4 } 5 f(); //error: a is not defined
這裡Firefox的控制檯中會報錯ReferenceError(引用錯誤):a 未被定義。。。。所以建議函式體內最好用var宣告變數,保持區域性性 如:
1 function f(){ 2 alert(a); 3 var a = 3; 4 } 5 f(); //undefined
這裡alert語句可以彈出,雖然是undefined ,但是沒有報錯,這是為什麼呢??
事實上,JS的解析過程分為兩個階段:預編譯期(預處理)與執行期。
預編譯期 JS會對本程式碼塊中的所有var宣告的變數和函式進行處理(類似與C語言的編譯),但需要注意的是此時處理函式的只是宣告式函式,而且變數也只是進行了宣告但未進行初始化以及賦值。
執行期 會按照程式碼塊的順序逐行執行。。
*函式內部 再次宣告賦值,函式f()內有區域性變數a時,會優先使用自己的變數,只不過第一次alert時未賦值
1 var a = 1; 2 function f(){ 3 alert(a); 4 var a = 3; 5 alert(a); 6 } 7 8 f(); //undefined 和 3
*函式內部 再次全域性宣告,會修改全域性的a
1 var a = 1; 2 function f(){ 3 alert(a); 4 a = 2; 5 alert(a); 6 } 7 f(); //1 和 2
*函式內全域性賦值一次,var宣告一次 函式f()內還是會優先使用自己的變數a
var a = 1; // 函式f()內變數a的執行順序 function f(){ alert(a); a = 2; // #2 alert(a); var a = 3; //等價於 var a ; #1 // a = 3 ; #3 alert(a); } f(); //undefined 2 和 3 alert(a); //1
函式f()內 變數a 宣告與賦值 的執行順序如上,應該很明確了!!
*一個經典的例子複習一下:
1 var a,b; 2 (function(){ 3 alert(a); //undefined 4 alert(b); //undefined 5 var a=b=3; //等價於 var a = 3 ; b = 3; b是全域性的 6 alert(a); //3 7 alert(b); //3 8 })(); 9 alert(a); //undefined 10 alert(b); //3
三、總結
1、JS的解析過程分為兩個階段:預編譯期(預處理)與執行期。
預編譯期 JS會對本程式碼塊(兩個script塊互不影響)中的所有var宣告的變數和函式進行處理(類似與C語言的編譯)
此時處理函式的只是宣告式函式,而且變數也只是進行了宣告但未進行初始化以及賦值。
執行期 會按照程式碼塊的順序築行執行
2、把執行方法寫在函式定義之前是不太規範的,但這個界限被弱化了。如今在一個作用範圍之內,都可以被正常呼叫。
所以,建議和優化如下:
1.函式體內變數最好var宣告為區域性,保持安全性和區域性性。
2.所有變數的宣告最好一次性寫在作用域的頂端,函式不必需如此,如:
1 function f(){ 2 var a, b, c; 3 4 a = "abc"; 5 b = [1,3,1]; 6 c = 12; 7 }
3.函式的執行方法 最好在 函式的定義 之後
作者:沒錯high少是我