1. 程式人生 > 其它 >淺談JavaScript的函式表示式(遞迴)

淺談JavaScript的函式表示式(遞迴)

  遞迴函式,在前面的部落格中已經簡單的介紹了。遞迴函式是一個通過函式名稱在函式內部呼叫自身的函式。如下:

1 function fac(num){
2                         if(num<1){
3                             return 1;
4                         }
5                         else{
6                             return num*fac(num-1);
7                         }
8                     }

  上面的程式碼,在第一行聲明瞭一個fac函式,同時在6行呼叫了fac函式本身。這是一個求階乘的遞迴函式。

1 var anthorfacc=fac;
2                     fac=null;
3                     anthorfacc(4);//丟擲異常

  上面的程式碼,在第一行聲明瞭一個變數anthorfacc,並指向fac。第2行將fac設定null,這樣anthorfacc也同樣為null。第3行呼叫的時候會丟擲異常,因為在求階乘的時候要兩次呼叫fac函式,但是fac設定為null之後,事實上fac的引用只剩一個。此時,在函式內部呼叫fac會報錯。在這種情況下,使用arguments.callee可以解決上面的問題。

  arguments.callee是一個指向執行函式的指標,可以用這個方法實現函式的遞迴呼叫。

 1 function fac(num){
 2                         if(num<1){
 3                             return 1;
 4                         }
 5                         else{
 6                             return num*arguments.callee(num-1);
 7                         }
 8                     }
 9                     var anthorfacc=fac;
10                     fac=null;
11                     var jie=anthorfacc(4);
12                     console.log(jie);//24

  上面的程式碼用arguments.callee代替了函式本身,即使將fac設定為null,依然不會報錯。但是在es5中的嚴格模式是不允許使用callee方法,訪問這個屬性會報錯。可以使用命名函式表示式來表達相同的結果。

 1 var fac=(function f(num){
 2                         if(num<1){
 3                             return 1;
 4                         }
 5                         else{
 6                             return num*fac(num-1);
 7                         }
 8                     });
 9                     var anthorfacc=fac;
10                     fac=null;
11                     var jie=anthorfacc(4);
12                     console.log(jie);//24

  上面的程式碼建立了一個名為f的命名函式表示式,然後將它的值賦給fac。即使將函式fac賦值給另外一個變數,函式f依然有效,所以遞迴函式依然有效。這種使用在嚴格模式和非嚴格模式都可以使用。