一、callee
在學習callee之前,需要先學習arguments。
arguments:
- 含義:該對象代表正在執行的函數和調用它的函數的參數。
- 語法:
[function.]arguments[n]
參數:function :當前正在執行的 Function 對象的名字。
n :要傳遞給 Function 對象的從0開始的參數值索引。
- 說明:在前面執行上下文的學習過程中,知道生成執行上下文需要兩個階段,分別是進入執行上下文和執行階段。在其中的進入執行上下文階段中,需要做三個工作,其中一個工作是創建幷初始化AO,即arguments對象。
-
Arguments Objects 是函數上下文里的激活對象AO中的內部對象,它包括下列屬性:
- callee:指向當前函數的引用
- length: 真正傳遞的參數的個數
- properties-indexes:就是函數的參數值(按參數列表從左到右排列)
而其中第一個就是今天需要學習的一個屬性。先看一個例子:
function add(a,b){ console.log(arguments.callee); return a+b; } add(3,4);
結果:
從結果可以看到,callee是一個指針,指向擁有這個arguments對象的函數。那么可以用這個屬性可以做什么?再看一個例子:
function fac(num){ if(num <= 1){ //0的階乘也是1 return 1; } else{ return num*fac(num-1); } } var trueFac = fac; fac = function(num){ return 0; }; console.log(trueFac(10));
結果:
結果並不是我們想要的,造成這個結果的原因就是在后邊更改了fac,fac()永遠返回0,而trueFac()方法中利用了fac()方法,造成了結果是0。解決這個問題就可以使用arguments.callee屬性。
代碼改為:
function fac(num){ if(num <= 1){ //0的階乘也是1 return 1; } else{ return num*arguments.callee(num-1); } } var trueFac = fac; fac = function(num){ return 0; }; console.log(trueFac(10));
結果為:
arguments.callee指向arguments對象的擁有函數引用,當把fac的函數引用賦給trueFac后,arguments對象的擁有函數變成了trueFac,所以結果是正確的。
二、caller
caller與callee不同,caller屬性並不屬於arguments對象,它是函數對象的屬性,Opera的早期版本不支持,這個屬性保存着調用當前函數的函數的引用。
例子:
function outer(){ inner(); } function inner(){ console.log(inner.caller); } outer();
結果:
從結果可知,因為outer()調用了inner(),所以inner.caller就指向outer()。