単純なJavaScript関数定義の問題
-
09-10-2019 - |
質問
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 が定義されていないというエラーが発生することです。これはどうすれば解決できますか?
解決
アップデート
更新されたコードは元のコードとはかなり異なります。問題は渡している文字列のようです setTimeout
(これには驚きましたが、簡単に再現できました)。私なら、変えるね
function First () {
setTimeout("Second()", 50)
};
に
function First () {
setTimeout(Second, 50);
}
...またはパラメータを渡す必要がある場合は、 Second
:
function First() {
setTimeout(function() {
Second(param0, param1);
}, 50);
}
(必要ないことに注意してください) ;
関数宣言の最後、ただし次の 1 つ後 setTimeout
間違いはないだろう[実際には失敗しないだろう] 必要 この場合、恐ろしい「セミコロン挿入」が自動的に挿入されますが...]。)
上記の 2 番目と 3 番目のバージョンでは、関数参照が使用されています。オリジナルでは文字列が使用されており、その後コンパイルされますが、これは不必要であり、問題があるようです( 文字列を使用したこの例は失敗します, 、 しかし これは関数参照を使用して機能します).
元の回答
以下の回答の時点で、質問で引用されたコードは次のとおりです。
function First() {Second();};
function Second() {First();};
そのコードは問題なく動作します。それは無限ループです(まあ、そうではありません) 無限, なぜなら、最終的には実装に戻りアドレス用のスタック領域がなくなるからです)、しかしそれが原因で爆発するまでは正常に動作します。 例
あなたの場合は失敗します 実際の コードは次のようになります。
var First = function() {
Second();
};
First();
var Second = function() {
First();
};
...それは大きく異なるため、関数を使用します 表現 関数ではなく (ステップバイステップのコードの一部として処理されます) 宣言 (スコープに入ったときに、ステップバイステップのコードの前に処理されます) を呼び出します。 First
前に Second
と定義されています。見る StackOverflow のこの他の回答 関数式と関数宣言の区別の詳細については、「関数式」を参照してください。
他のヒント
わかりました、私はあなたの問題を見ていると思います。私はあなたのコードが関数の中に包まれているに違いないよね?次に、機能のようなものはありません。
これは機能しません:
(function() {
function First () {
setTimeout("Second()", 50)
}
function Second () {
alert('hi!');
}
First();
})();
しかし、これは機能します:
(function() {
function First () {
setTimeout(Second, 50)
}
function Second () {
alert('hi!');
}
First();
})();
私はあなたのコードを試してみて、「second();」と呼ばれます。最初。 Chromeで正常に機能しました。もちろん永遠にループします。
JavaScriptでは、関数の呼び出し時に非常に遅れて拘束されます。グローバルオブジェクトは、非常に遅い「バインドされる」別の変数でもあります。すべてがいつでも(非同期的に)変化する可能性があるため、関数が別の関数を使用できるようにする必要がない理由です。 「欠落」関数は、関数が呼び出される直前に他のメカニズムによって追加される場合があります。関数が実行される直前にのみ、JS-Runtimeは、この機能がスコープで利用可能であるかどうかを確認する必要があります。
それがChromeで機能する理由です。 JavaScriptでは、あなたは実際にこのようなことをしています:
var GLOB = this; // bind global obj to variable
GLOB["First"] = function() {
GLOB["Second"]();
};
GLOB["Second"] = function() {
GLOB["First"]();
};
呼び出し GLOB["Second"]();
Chromeの魅力のように機能します(そしてもちろんループ)。おそらく、ブラウザ/JS-Implementation/Dev-Toolは関数定義に関してより制限的であり、それらが定義される前に機能を使用しないでください。
その後、これを使用できます obj["funcname"] = function() {}
構文 function funcname(){}
, 、しかし、「壊れた」js-interpreterによるエラーとして検出されない場合があります。
これが役立つことを願っています、Juve