js函數和變量的聲明與執行順序


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.函數的執行方法 最好在 函數的定義 之后

 

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM