関数がどこから呼び出されているかを見つけることは可能ですか?はいの場合、関数がから呼び出されているかどうかを検出する方法グローバルスコープ、別の関数から、またはおそらくブラウザコンソールから?
次の例を見てください。
_<script>
function myFunc1() {
// some code
myFunc2(); // I was called from myFunc1()
}
function myFunc2() {
var callerName = new String;
callerName = arguments.callee.caller.name;
// some code
alert('I was called from ' + callerName + ' function');
}
myFunc2(); // I was called from global scope
</script>
_
上記の例のこの行_callerName = arguments.callee.caller.name;
_は、呼び出し元関数の名前を教えてくれることを知っています。しかし、わかりません関数がグローバルスコープから呼び出されたかどうかを検出する方法。たとえば、myFunc2()
を変更し、_if else
_ステートメントを追加して_arguments.callee.caller.name
_はundefined
値を返します。これは、関数がグローバルスコープから呼び出されたときに発生することを認識しています。
_myFunc2() {
var callerName = new String;
callerName = arguments.callee.caller.name;
if(callerName == undefined) {
alert('I was called from global scope');
} else {
alert('I was called from ' + callerName + ' function');
}
}
_
ただし、myFunc2()
がグローバルスコープから呼び出され、_callerName = arguments.callee.caller.name;
_によってJavaScriptが次のエラーをスローする場合、これは機能しません。
_TypeError: 'null' is not an object (evaluating 'arguments.callee.caller.name')
_
だから私は正方形に戻りました、そして質問はまだ残っています:
Chromeでは、次を使用できます。
console.trace();
その行を関数に追加するだけです。通常、最初の行として配置します。コンソールを表示すると、関数の名前が表示され、その行の下に、関数がどこから呼び出されているかが表示されます。
関数がグローバルスコープから呼び出された場合、arguments.callee.caller.name
は未定義になります。それ以外の場合は、呼び出し元関数の名前になります(呼び出し元のスコープも表します)。
したがって、 厳密モード を除いて、すでに持っているものは機能するはずです。ここでarguments.callee
利用できません。
さらに、ブラウザから利用できる開発者ツールは、おそらくこの種のものを検査するためのより良い方法です。ブレークポイントを設定して、スタックトレースパネルを確認するだけです。もちろん、コード自体が実行時に呼び出しスコープを知る必要がない限り。
ブラウザによっては、たとえばtry/catch
内の未定義の変数にアクセスすることで、挑発してエラーが発生する可能性があります。次に、一部のブラウザがエラーで提供するスタックトレースを調べます。
これは非常にブラウザ固有です。
function func1() {
// some code
func2(); // I was called from func1()
}
function func2() {
var callerName = new String;
callerName = arguments.callee.caller ? arguments.callee.caller.name : "global";
if(callerName == "global") {
alert('I was called from global scope');
} else {
alert('I was called from ' + callerName + ' function');
}
}
func1();
func2(); // I was called from global scope
func2が呼び出されると、呼び出し元の名前が表示され、別の関数スコープ内で呼び出された場合はその関数の名前が表示され、グローバルスコープから呼び出された場合は、グローバルスコープから呼び出されたことを示すメッセージが表示されます。
JavaScriptでは、ほとんどのものはオブジェクトです。callerName = new String
を宣言すると、いくつかのプロパティとメソッドを使用してstringオブジェクトを作成します。たとえば、valueOf()
メソッドは、文字列オブジェクトのプリミティブ値を返します。 ただし、JavaScriptが示すように'TypeError: 'null' is not an object
nullはオブジェクトではありませんではなく、オブジェクトがないことです。 nullにはメソッドやプロパティがありません。関数がグローバルスコープから呼び出されると、arguments.callee.caller
は呼び出し元をnullに評価します。Soarguments.callee.caller.name
は次のようになります。nullのname
プロパティ(null.name
)にアクセスしようとしていますが、nullにはname
というプロパティがありません。オブジェクトではなく、できないためなんらかの財産を持っています。存在しないものにアクセスしようとしているため、JavaScriptが文句を言うのはこのためです。ただし、最初にcaller
かどうかを確認することができます。は偽の値です単純なif else
ステートメントを使用してif(!arguments.callee.caller)
、そうでない場合はname
のcaller
プロパティにアクセスして、どの関数を見つけることができますはmyFunc2()
、を呼び出しましたが、の場合、関数がグローバルスコープから呼び出されたことがわかります。
function myFunc2() {
if(!arguments.callee.caller) {
callerName = "global";
alert('I was called from global scope');
} else {
callerName = arguments.callee.caller.name;
alert('I was called from ' + callerName + ' function');
}
}
それはかなり難しい質問です。この回答で説明されているように、Arguments.calleeは一部のブラウザーで非推奨になっています。
アプローチに応じて、Function.callerを使用できます。私はかなり書いています 簡単な例
function A() {
if (A.caller === null || A.caller.name == "") console.log("Function called from top window")
else console.log("Called from " + A.caller.name);
B();
}
function B() {
if (B.caller === null || B.caller.name == "") console.log("Function called from top window")
else console.log("Called from " + B.caller.name);
}
A();
別のより一般的な例を見つけることができます ここ
それでも'use strict'
はこれらのアプローチを両方とも失敗させるので、try / catch
ブロックを使用すると問題を解決できるか、関数の " ダミーコールスタック "をシミュレートできます(事実に応じて)すべてのコードが同期して機能すること)