2

このコードはなぜですか:

    var myBreak = 'break;';
    for(var i=0; i < 5; i++) {
        console.log('i is : ' + i);
        eval(myBreak);
    }
    console.log('done !');

トリガー:

unlabelled break must be inside loop or switch

done !コンソールに戻る代わりにFirebugのエラーメッセージ?

eval()ステートメントを破ることはできませんか?

前もって感謝します !

編集 :

私は今混乱しています。^^

  • なぜ失敗するのですか?
  • Jack Wandersは、evalが独自の「実行コンテキスト」を持っているのでしょうか。
  • はいの場合、なぜ彼の例が機能しないのですか?
4

2 に答える 2

2

evalコードは独自の実行コンテキストで実行されます。基本的に、これは、実行時に、ループbreak;内で実行されていることを認識しないことを意味します。for

にラベルを付けるとbreak、機能するはずです。

var myBreak = 'break myLoop;';

myLoop:
  for(var i=0; i < 5; i++) {
    console.log('i is : ' + i);
    eval(myBreak);
  }

console.log('done !');
于 2012-08-14T23:00:47.683 に答える
2

evalは、JavaScriptインタープリターの新しいインスタンスでコードを解析/評価します。コードは最終的に元のインタープリターのコードとのコンテキストで実行されますが、新しいインスタンスはそれを認識しないため、コードはその外部コンテキストなしで実行できる必要があります。

したがってalert(eval(this.constructor.name))、適切なオブジェクトコンテキスト名(グローバルのウィンドウ)が与えられます。

ただし、これらは失敗します。これは、インスタンスが別々のインタープリターによって評価されるまで、インスタンスが互いのコードを「認識」しないためです。このフェーズでは、一方が他方なしで失敗します。

  • try{}eval('catch(){}');

  • for(;;){ eval('break;'); }

  • myLoop: eval('for(;;){ break myLoop; }');

短いバージョン:コードは期待どおりに機能しますが、eval内のすべてのものは、それ自体で他のコンテキストで起動できるものでなければなりません。

したがって、基本的に、値とスコープおよびオブジェクトコンテキストが考慮される前に、予備的な解析/エラーチェックが実行されます。それがすべて完了すると、コードは協調して動作し、まだ定義されていない変数を呼び出しているかどうかなどをチェックできます。その前は、新しいインタープリターは、エラーをチェックするときにevalの内容のみを確認します。そのブレークの場合、それが見えないのはそれを囲むループまたはスイッチです。

ループラベルはこの初期の解析/評価フェーズで考慮されますが、varの存在や関数ラベルなどは後でチェックされるように見えます。

于 2012-08-14T23:36:27.207 に答える