0

アップデート:

おそらく、関数の呼び出し方法に問題があるので、次のようにします。

2 つの JS ファイル
  Main.js: '(on)load' イベントのイベント リスナーを追加する自己呼び出し (厳密ではない) 関数。
コールバックは、location.pathname を解析するローダー関数を呼び出し、init 関数を呼び出し、'(on)load' リスナーをデタッチ/削除して、(明示的に) null を返します。

  PageSpecific.js: _init 関数を含み、ボディにいくつかのイベント リスナーを追加します。
これらのリスナーのコールバック (クロージャーからも返される) の 1 つは、argument.callee を再帰の参照として使用する厳密な関数を呼び出します。
イベントハンドラーを返すクロージャーは、ブラウザーに応じて、または他のイベントをバインドおよびバインド解除しない場合がありますが、IE <9 で onchange イベントを模倣するため、ここでは関係ないと思います。

これがかなり明確であることを願ってい
ます。F => eventlistener
             => ハンドラー (名前付きだが anon F で宣言) => pageloader =>
                  init => クロージャー
                  によって返される eventListener バインディング関数
                      => strict 関数を呼び出す

ちなみに、これは私が実際に使用している、呼び出された関数の縮小版です。_initより具体的には、イベント リスナーとハンドラーをバインドするクロージャーです。それは私の長い質問のもう1つであり、誰も答えを知らないようです...ヒント;-)


かなり大きな (そして複雑な) JavaScript をデバッグしています。これを行う際に、厳密なモードを使用して正常に動作する関数があることに気付きましたが、間違っていなければエラーをスローする必要があります。スクリプトはかなり大きくて複雑なので (イベント委任、スタック クロージャなど)、簡単な例を次に示します。

function withCalleeRecursion(foo)
{
    'use strict';//strict throws typeError on arguments.callee
    foo = foo.replace(/(a|b)+/gi, function (p1,p2)
    {
        if (p1.match(/(a|b){2,}/i))
        {
            return p1.replace(/(a|b)/gi,arguments.callee);//no errors
        }
        return (p2.match(/a/i) ? 'X':'Y');
    });
    return foo;
}

(function()
{//not strict
    alert(withCalleeRecursion('Abba makes me barf'));
})();

私の実際のスクリプトでは、これは問題なく動作します。これを Firebug と chrome コンソールの両方に貼り付けると、エラーがスローされます。ここでこのコードを試したので、IE もエラーをスローするはずですが、IE のデバッガーでコードを実行すると、問題なく動作します。私が解決できる限り、doctype (html5 と html4 を試した) を変更しても違いはありません。

(ほとんどの) ブラウザーは、その'use strict';名前が示すようにディレクティブに厳密ではないと考えているのは正しいですか? スクリプトの解析時にエラーの可能性が検出された場合、ブラウザはそれを無視することを選択しているようです。これは本当ですか?


その間、予防措置として、機能にわずかな変更を加えました。calleeここで、厳密モードで参照を取得する方法を知りたがっている人々のかなりの数の質問を見たので、ここにも貼り付けます。

function withCalleeRecursion(foo)
{
    'use strict';
    foo = foo.replace(/(a|b)+/gi, function abR(p1,p2)
    {
        if (p1.match(/(a|b){2,}/i))
        {
            return p1.replace(/(a|b)/gi,abR);
        }
        return (p2.match(/a/i) ? 'X':'Y');
    });
    return foo;
}

コールバックに名前を付けます。それだけです。

4

2 に答える 2

2

これはおそらく、ブラウザ コンソールが を使用eval()しているためです。"use strict";に渡されるコードの文字列の先頭に置くことはeval()期待どおりに機能しますが、コンソールの実装によって、コンソールに入力した文字列の前にコードが追加される可能性が"use strict";あります。つまり、それは実行される最初のステートメントではなくなり、無視されます。

次の記事に、これへの参照と推奨される回避策があります。

http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/

推奨される回避策は、すぐに実行される関数内でコンソールのコードをラップすることです。

(function() {
    "use strict";
    nonExistentVariable = 1; // Error is now thrown
})();
于 2012-07-05T13:48:05.573 に答える
0

この記事を読めば理解が深まるかもしれません。とにかく、解決策はあなたが言及したものです。エラーは、arguments.callerおよびarguments.calleeへのアクセスが厳密モードで例外をスローするためです。したがって、参照する無名関数には名前を付ける必要があります。

于 2012-07-05T13:36:11.663 に答える