1. ホーム
  2. javascript

[解決済み] ECMAscriptのストリクトモードを特定の関数で無効にすることはできますか?

2023-07-04 01:49:48

質問

MDC や ECMAscript の仕様書には、私の質問に関するものは何もありません。おそらく、誰かがこれを解決するために、より「厄介な」方法を知っているのでしょう。

私は "use strict" を呼び出しています。すべてのファイルはこのように始まります。

(function(win, doc, undef) {
    "use strict";

    // code & functions
}(window, window.document));

さて、私はエラーを処理するカスタム関数を持っています。この関数は .caller プロパティを使って コンテキストスタックトレース . このように見える。

var chain = (function() {
    var _parent = _error,
        _ret = '';

    while( _parent.caller ) {
        _ret += ' -> ' + _parent.caller.name;
        _parent = _parent.caller;
    }

    return _ret;
}());

しかし、もちろん、ストリクトモードでは .caller は削除不可能なpropであり、取得時にスローします。そこで質問なのですが、どなたか を無効にする strict more "機能的な"?

"use strict"; は、それが呼ばれた後のすべての関数によって継承されます。これで、特定の関数でだけストリクトモードを使用することができるようになりました。 "use strict"; を呼び出すことで、特定の関数でストリクトモードを使用することができますが、その逆を実現する方法はありますか?

どのように解決するのですか?

機能ごとにストリクトモードを無効にすることはできません。

ストリクトモードが機能することを理解することは重要です。 字義通り つまり、実行ではなく、関数の宣言に影響します。どんな関数も 宣言された で宣言された関数は、それ自体がストリクト関数になります。しかし、どんな関数も と呼ばれる は必ずしもストリクトであるとは限りません。

(function(sloppy) {
  "use strict";

   function strict() {
     // this function is strict, as it is _declared_ within strict code
   }

   strict();
   sloppy();

})(sloppy);

function sloppy(){
  // this function is not strict as it is _declared outside_ of strict code
}

関数 を定義できることに注意してください。 を定義し、それをストリクトの関数に渡していることに注目してください。

あなたの例で似たようなことをすることができます - "sloppy" 関数でオブジェクトを持ち、そのオブジェクトを直ちに呼び出されたストリクト関数に渡すのです。もちろん、quot;sloppy" 関数が主ラッパー関数内から変数を参照する必要がある場合、それはうまくいきません。

また、以下のことに注意してください。 間接的な評価 - はここでは役に立ちません。間接評価はグローバルな文脈でコードを実行するだけです。ローカルに定義された関数を呼び出そうとしても、間接的なevalはそれを見つけることすらできません。

(function(){
  "use strict";

  function whichDoesSomethingNaughty(){ /* ... */ }

  // ReferenceError as function is not globally accessible
  // and indirect eval obviously tries to "find" it in global scope
  (1,eval)('whichDoesSomethingNaughty')();

})();

グローバル eval に関するこの混乱は、おそらくグローバル eval がストリクトモード内からグローバルオブジェクトにアクセスするために使われるという事実に由来しています (これは単純に this でアクセスできるわけではありません)。

(function(){
  "use strict";

  this; // undefined
  (1,eval)('this'); // global object
})();

しかし、質問に戻ると...

あなたは一種のごまかしで、新しい関数を Function コンストラクタで新しい関数を宣言することができます。 を継承していません。 しかし、それは(非標準の)関数展開に依存することになり、あなたは 外部変数を参照する能力を失う .

(function(){
  "use strict";

  function strict(){ /* ... */ }

  // compile new function from the string representation of another one
  var sneaky = Function('return (' + strict + ')()');

  sneaky();
})();

FF4+ は (私が見たところ) 仕様に反しているようで、(私が見たところ) Function を介して作成された関数を厳格なものとして誤ってマークします。これは、他の strict-mode をサポートする実装では起こりません。 (Chrome 12+、IE10、WebKit など) の実装では発生しません。