0
function First () {
setTimeout("Second()", 50)
};

function Second () {  //I'm very confident this conditional works fine
 if  (document.getElementsByClassName("l")[0].href ==
      document.getElementById("myFrame").getAttribute("src"))  
   {  
   First();                                       
   }
 else
   {
   var newLink = document.getElementsByClassName("l")[0].href;        //
   document.getElementById("myFrame").setAttribute("src", newLink);
   }};

First ();

問題は、First() が定義されているときに、Second が定義されていないというエラーが発生することです。これはどのように解決できますか?

4

3 に答える 3

4

アップデート

更新されたコードは、元のコードとはかなり異なります。問題は、渡された文字列にあるようですsetTimeout(これには驚きましたが、簡単に再現できました)。私なら、変えるね

function First () {
    setTimeout("Second()", 50)
};

function First () {
    setTimeout(Second, 50);
}

...またはパラメータをに渡す必要がある場合Second:

function First() {
    setTimeout(function() {
        Second(param0, param1);
    }, 50);
}

;(関数宣言の最後に a は必要ないことに注意してください。ただし、1 つ後にsetTimeoutは間違いはありません [実際には必要ありません。この場合、「セミコロン挿入」という恐怖がそれを挿入します)。 、 しかし...]。)

上記の 2 番目と 3 番目のバージョンでは、関数参照が使用されています。オリジナルはコンパイルされた文字列を使用しますが、これは不要であり、問​​題のようです (文字列を使用したこの例は失敗しますが関数参照を含むこの例は機能します)。

元の回答

以下の回答の時点で、質問で引用されているコードは次のとおりです。

function First() {Second();};
function Second() {First();};

そのコードは問題なく動作します。これは無限ループです (まあ、無限ではありません。最終的に実装には戻りアドレス用のスタック スペースがなくなるからです) が、それが原因で爆発するまでは問題なく動作します。

実際のコードが次のようになっていると失敗します。

var First = function() {
    Second();
};
First();
var Second = function() {
    First();
};

...それは非常に異なるため、関数宣言(スコープへのエントリ時に、ステップバイステップ コードの前に処理される) ではなく、関数(ステップバイステップ コードの一部として処理される) を使用します。そして、定義される前にへの呼び出しがあります。関数式と関数宣言の違いの詳細については、StackOverflow に関するこの他の回答を参照してください。FirstSecond

于 2011-01-10T23:48:26.657 に答える
1

わかりました、私はあなたの問題を見たと思います。あなたのコードは関数内にラップされているに違いありませんよね?その場合、関数 Second などは存在しません。

これは機能しません:

(function() {
    function First () {
        setTimeout("Second()", 50)
    }
    function Second () {
        alert('hi!');
    }
    First();
})();

しかし、これはうまくいきます:

(function() {
    function First () {
        setTimeout(Second, 50)
    }
    function Second () {
        alert('hi!');
    }
    First();
})();
于 2011-01-11T00:26:16.570 に答える
0

私はちょうどあなたのコードを試して、「Second();」と呼びました 最初。Chromeでは問題なく動作しました。もちろん永遠にループします。

Javascript では、変数は関数呼び出しの非常に遅い時間にバインドされます。グローバルオブジェクトも、非常に遅く「バインド」される別の変数です。すべてがいつでも (非同期に) 変更される可能性があるため、関数が別の関数が使用可能であることを要求してはなりません。「欠落している」関数は、関数が呼び出される直前に他のメカニズムによって追加される可能性があります。関数が実行される直前にのみ、JS ランタイムは、この関数がスコープ内で使用可能かどうかを確認する必要があります。

そのため、Chrome で動作します。Javascriptでは、実際に次のようなことをしています:

var GLOB = this; // bind global obj to variable

GLOB["First"] = function() {
   GLOB["Second"]();
};

GLOB["Second"] = function() {
   GLOB["First"]();
};

呼び出しGLOB["Second"]();は Chrome の魅力のように機能します (もちろんループします)。おそらく、ブラウザ/JS実装/開発ツールは関数定義に関してより制限的であり、定義される前に関数を使用しないようにします.

次に、このobj["funcname"] = function() {}構文を使用できます。これは と同じfunction funcname(){}ですが、「壊れた」JS インタープリターによってエラーとして検出されない場合があります。

これがお役に立てば幸いです、ユーヴェ

于 2011-01-11T00:25:59.817 に答える