在函數內部,有兩個特殊的對象:arguments 和 this。其中, arguments 的主要用途是保存函數參數, 但這個對象還有一個名叫 callee 的屬性,該屬性是一個指針,指向擁有這個 arguments 對象的函數。 請看下面這個很是經典的階乘函數javascript
function factorial(num){ if (num <=1) { return 1; } else { return num * factorial(num-1) } }
定義階乘函數通常都要用到遞歸算法;如上面的代碼所示,在函數有名字,並且名字之後也不會變 的狀況下,這樣定義沒有問題。但問題是這個函數的執行與函數名 factorial 牢牢耦合在了一塊兒。爲 了消除這種緊密耦合的現象,能夠像下面這樣使用 arguments.calleehtml
function factorial(num){ if (num <=1) { return 1; } else { return num * arguments.callee(num-1); } }
在這個重寫後的 factorial()函數的函數體內,沒有再引用函數名 factorial。這樣,不管引用 函數時使用的是什麼名字,均可以保證正常完成遞歸調用。例如java
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高程第三版函數
版權聲明:本文爲博主原創文章,未經博主容許不得轉載。post
caller返回一個函數的引用,這個函數調用了當前的函數;callee放回正在執行的函數自己的引用,它是arguments的一個屬性this
caller
caller返回一個函數的引用,這個函數調用了當前的函數。
使用這個屬性要注意:
1 這個屬性只有當函數在執行時纔有用
2 若是在javascript程序中,函數是由頂層調用的,則返回nullurl
functionName.caller: functionName是當前正在執行的函數。spa
null.net
callee
callee放回正在執行的函數自己的引用,它是arguments的一個屬性
使用callee時要注意:
1 這個屬性只有在函數執行時纔有效
2 它有一個length屬性,能夠用來得到形參的個數,所以能夠用來比較形參和實參個數是否一致,即比較arguments.length是否等於arguments.callee.length
3 它能夠用來遞歸匿名函數。