js函式和變數的執行順序【易錯】

weixin_30639719發表於2020-04-05

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少是我                                                                                                                                                                                     

  出處:http://www.cnblogs.com/highshao/                                                                                                         
  本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。

 

轉載於:https://www.cnblogs.com/highshao/p/5442460.html

相關文章