arguments.callee 屬性 遞歸調用 & caller和callee的區別


arguments.callee

 

在函數內部,有兩個特殊的對象:arguments 和 this。其中, arguments 的主要用途是保存函數參數, 但這個對象還有一個名叫 callee 的屬性,該屬性是一個指針,指向擁有這個 arguments 對象的函數。 請看下面這個非常經典的階乘函數

復制代碼
function factorial(num){    
   if (num <=1) {         
      return 1;     
   } else {         
   return num * factorial(num-1)     
   } 
}  
復制代碼

定義階乘函數一般都要用到遞歸算法;如上面的代碼所示,在函數有名字,而且名字以后也不會變 的情況下,這樣定義沒有問題。但問題是這個函數的執行與函數名 factorial 緊緊耦合在了一起。為 了消除這種緊密耦合的現象,可以像下面這樣使用 arguments.callee

復制代碼
function factorial(num){    
   if (num <=1) {         
      return 1;     
   } else {         
   return num * arguments.callee(num-1);
   } 
}  
復制代碼

在這個重寫后的 factorial()函數的函數體內,沒有再引用函數名 factorial。這樣,無論引用 函數時使用的是什么名字,都可以保證正常完成遞歸調用。例如

復制代碼
        function factorial(num){
            if(num <= 1){
                return 1;
            }else{
                return num * arguments.callee(num-1);
            }
        }
        var trueFactorial = factorial;
        alert(trueFactorial(5));    //120    

factorial = function() { return 0; } alert(trueFactorial(5));// 120 如果沒有使用arguments.callee,將返回0
復制代碼

在此,變量 trueFactorial 獲得了 factorial 的值,實際上是在另一個位置上保存了一個函數 的指針。然后,我們又將一個簡單地返回 0的函數賦值給 factorial 變量。如果像原來的 factorial() 那樣不使用 arguments.callee,調用 trueFactorial()就會返回 0。可是,在解除了函數體內的代 碼與函數名的耦合狀態之后,trueFactorial()仍然能夠正常地計算階乘;至於 factorial(),它現 在只是一個返回 0的函數。 

 

參考自js高程第三版

 
 
標簽:  JavaScript
 
 
 

caller和callee的區別

 分類:

caller返回一個函數的引用,這個函數調用了當前的函數;callee放回正在執行的函數本身的引用,它是arguments的一個屬性

caller
caller返回一個函數的引用,這個函數調用了當前的函數。
使用這個屬性要注意:
1 這個屬性只有當函數在執行時才有用
2 如果在javascript程序中,函數是由頂層調用的,則返回null

functionName.caller: functionName是當前正在執行的函數。

 

[javascript]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. var a = function() {   
  2. alert(a.caller);   
  3. }   
  4. var b = function() {   
  5. a();   
  6. }   
  7. b();  

上面的代碼中,b調用了a,那么a.caller返回的是b的引用,結果如下:

 

 

[javascript]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. var b = function() {   
  2. a();   
  3. }   
如果直接調用a(即a在任何函數中被調用,也就是頂層調用),返回null:

 

 

[javascript]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. var a = function() {   
  2. alert(a.caller);   
  3. }   
  4. var b = function() {   
  5. a();   
  6. }   
  7. //b();   
  8. a();  
輸出結果:

 

null

callee
callee放回正在執行的函數本身的引用,它是arguments的一個屬性
使用callee時要注意:
1 這個屬性只有在函數執行時才有效
2 它有一個length屬性,可以用來獲得形參的個數,因此可以用來比較形參和實參個數是否一致,即比較arguments.length是否等於arguments.callee.length
3 它可以用來遞歸匿名函數。

 

[javascript]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. var a = function() {   
  2. alert(arguments.callee);   
  3. }   
  4. var b = function() {   
  5. a();   
  6. }   
  7. b();  
a在b中被調用,但是它返回了a本身的引用,結果如下:
[javascript]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. var a = function() {   
  2. alert(arguments.callee);   
  3. }   


免責聲明!

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



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