私は最近 JavaScript を学び、呼び出し元と呼び出し先で問題が発生したため、オンラインの Baidu によくアクセスしました。見つかった内容は誰にとっても非常に有益なので、共有するためにまとめました。
caller: 関数 function を呼び出す関数への参照を返します (使用法: function.caller)
注: 関数の場合、caller 属性は関数の実行時にのみ定義されます。関数がトップレベルから呼び出された場合、caller は null になります。
var time = 3 //控制次数,去掉会一直在caller与handleCaller交替不断执行 function caller() { caller.caller()//返回调用caller函数的函数引用 } function handleCaller() { if (time > 0){ time-- alert(handleCaller.caller)//返回调用handleCaller函数的函数引用 alert(caller.caller)//返回调用caller函数的函数引用 caller() } } handleCaller()
分析の例: handleCaller が初めて実行されると、両方のアラートが null を返します。値がnullです。次に、caller() 関数が呼び出されます。caller.caller は、それを呼び出した関数 (handleCaller) への参照を返します。handleCaller 関数は、caller.caller() を通じて再度呼び出すことができます。 handleCaller が 2 回目に実行されると、alert(handleCaller.caller) は呼び出し元コード (実際には呼び出し元への参照) を返し、alert(caller.caller) は handleCaller コードを返します。関数間の呼び出し関係は、handleCaller->caller->handleCaller であるためです。その後、2 つの機能が交互に繰り返されます。
caller は現在の関数を呼び出す関数を指しますが、グローバル スコープ (つまりトップレベル ウィンドウ) で呼び出された場合は null が返されることが 1 つあります。
コードの開始
==================== function testCaller(){ if(testCaller.caller == null){ console.log('accessed at global'); }else{ console.log('accessed at ' + testCaller.caller); } }
世界中に電話をかける
testCaller(); // accessed at global
呼び出し
function a(){ testCaller(); } a(); // accessed at function a(){testCaller();}
この時点で、testCaller.caller は関数 a を指します
callee: 対応する引数の関数参照を返します。 (主に匿名関数の再帰に使用されます)
注: おそらくインターネット上で最もよく目にするのは、呼び出し先が実行中の関数への参照を返すというものです。これが私が理解している方法です。各関数には独自の引数があり、通常はパラメーターを格納するために使用されます。引数にはcallee属性があり、初期値は自身に対応する関数参照になります。関数がこのステートメントを実行するとき、引数はデフォルトで現在実行中の関数に対応し、arguments.callee は現在実行中の関数への参照になります。もちろん、他の関数の引数 (この例では args) をマークした場合は、当然のことながら args.callee() を使用してその関数を再度呼び出すことができます。
function a(){ alert(arguments.callee) var args = arguments function c(){ alert(arguments.callee) args.callee() } c() } a()
分析例: この例の argument.callee は、デフォルトで現在実行中の関数への参照を返します (a は a 自身の関数参照を返し、c は c 自身の関数参照を返します)。また、 args を使用して関数の引数を格納することにより、組み込み関数 c で args.callee() を使用して、関数 a を再度呼び出します。
==================== function a(x){ if(x<=1) return x; else return x + a(x-1); } a(12) // 78
これは、正常な結果をもたらす最小限の再帰です。
以下の呼び出しメソッドを見てください
var b = a; a = null; // 将a回收 b(12); // erro : 'a' is not a function
理由も簡単で、b=a, b=function a(){}; b を呼び出す前に、a=null を使用しました。したがって、関数 a が実行されているとき、a は関数 a ではなく null を返します。
そこで、エラーを報告し、この問題を解決する方法を教えてください。 a を別の方法に変更しましょう
function a(x){ if(x<=1) return x; else return arguments.callee(x-1); // 这句是改变的地方 }
もう一度電話してください
var b = a; a = null; b(12); // 78
理由: a=null を設定しましたが、a は関数 a では使用されず、arguments.callee を通じて現在の関数を指します。
これは、arguments.callee の定義が次のとおりであるためです。実行中の関数を返します。