web-dev-qa-db-ja.com

'caller'および 'arguments'は制限された関数プロパティであり、このコンテキストではアクセスできません

次のように、関数の呼び出し元を単純に表示する単純なデバッグ関数を作成しようとしています。

_function xe() {
  console.log(xe.caller().name)
}
_

これにより、関数にxe()を追加するだけで、関数の呼び出しをログに記録できます。デバッグを支援するための短い、簡単な追加です。いわば、砂糖のデバッグです。

残念ながら、件名からエラーが表示されます。

TypeError: 'caller'および 'arguments'は制限された関数プロパティであり、このコンテキストではアクセスできません。

すべてのモジュールの先頭に_"use strict"_を挿入するBabel/ES6を使用しています。これはmayの原因ですが、検索の結果、エラーが発生した理由に関する限られた情報しか得られなかったため、よりよく理解したいと思います。

ストリクトモードが問題になる場合は、モジュール/機能だけでプロジェクト全体でストリクトモードを無効にしないことをお勧めします。

20
Brian M. Hunt

それが原因です。 MDNから

strictモードでは、一般に実装されているECMAScriptの拡張機能を介してJavaScriptスタックを「ウォーク」することはできなくなりました。これらの拡張機能を備えた通常のコードでは、関数funが呼び出される途中で、fun.callerは最後にfunを呼び出した関数であり、fun.argumentsはそのfunの呼び出しの引数です。両方の拡張機能は、「保護された」コードが「特権のある」関数と(潜在的に保護されていない)引数にアクセスできるため、「保護された」JavaScriptに対して問題があります。 funがstrictモードの場合、fun.callerとfun.argumentsは両方とも、設定または取得時にスローされる削除不可能なプロパティです。

ES6を実行している場合、一般的な場合、厳格モードを無効にすることはできません。 ES6モジュールの場合など、 特定の条件 の間は暗黙的です。

デバッグするだけなら、デバッガでブレークポイントを使用してスタックフレームをチェックすることをお勧めしますが、それはすでに知っていると思います。

デバッグ情報を出力するだけの場合も、Errorオブジェクトのスタックを読み取るだけだと思います。

_console.log(new Error().stack);
_

globaly disable (しかし、これはあなたが望むものではないことを理解しています)_use strict_ with babel

_require("6to5").transform("code", { blacklist: ["useStrict"] });
_

または

_$ 6to5 --blacklist useStrict
_

モジュールレベルで削除する必要がある場合は、自分で行う必要があると思います。おそらく基本的な文字列を置き換えますか?

さらに、ES5で指摘されているように。 xe.caller().nameではなく_xe.caller.name_である必要があります。そうでない場合は、関数を再度呼び出します。

22
Kit Sunde

this ドキュメントに従って。 Function.caller()プロパティは、指定された関数を呼び出した関数を返します。 xe.callerを使用すると、単に呼び出し元関数全体を取得できます。ここでも、呼び出し元の関数を実行しています。ここでは、recursionを実行しています。これが、strictモードで許可されない理由です。

ブラウザコンソールでサンプル関数を実行できます。 Maximum call stack size exceededエラーが発生します。

1
Laxmikant Dange