[解決済み】Javascriptのinfamous Loop問題?重複
2022-04-07 09:48:05
質問
次のようなコード・スニペットを持っています。
function addLinks () {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function () {
alert(i);
};
document.body.appendChild(link);
}
}
上記のコードは、5つのリンクを生成し、各リンクに現在のリンクIDを表示するアラートイベントをバインドするものです。しかし、これはうまくいきません。生成されたリンクをクリックすると、すべて "link 5" と表示されます。
しかし、次のコード・スニペットは期待通りに動作します。
function addLinks () {
for (var i=0, link; i<5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
link.onclick = function (num) {
return function () {
alert(num);
};
}(i);
document.body.appendChild(link);
}
}
上記2つのスニペットは、以下のサイトから引用しています。 ここで . 著者の説明では クロージャ が魔法をかける。
しかし、その仕組みとHow クロージャ は、すべて私の理解を超えています。なぜ前者はうまくいかず、後者はうまくいくのでしょうか?どなたか、このマジックについて詳しい説明をお願いします。
解決方法は?
引用元 は、最初の例の説明のため。
JavaScript のスコープはブロックレベルではなく関数レベルです。クロージャを作成すると、そのスコープを囲む関数のレキシカル環境に追加されるだけです。
ループが終了すると、関数レベルの変数iは値5となり、それが内部関数に「見える」ことになる。
2つ目の例では、繰り返しステップごとに、外側の関数リテラルは独自のスコープとローカル変数を持つ新しい関数オブジェクトに評価されます。
num
の現在の値が設定される。
i
. として
num
関数オブジェクトは独立しているので、次の反復ステップで古い値が上書きされることはありません。
この方法は、各リンクに対して2つの新しい関数オブジェクトを作成しなければならないので、かなり非効率的であることに留意してください。DOM ノードを情報の保存に利用すれば、簡単に共有することができるので、これは不要です。
function linkListener() {
alert(this.i);
}
function addLinks () {
for(var i = 0; i < 5; ++i) {
var link = document.createElement('a');
link.appendChild(document.createTextNode('Link ' + i));
link.i = i;
link.onclick = linkListener;
document.body.appendChild(link);
}
}
関連
-
[解決済み】JavaScriptのgetElementByNameが機能しない
-
[解決済み】Javascriptのコールバック関数がFirefoxで「Callback is not a function」というエラーを投げる
-
[解決済み】SyntaxError: 期待された式が、'<'を得た。
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] ループ内のJavaScriptクロージャ - シンプルな実用例
-
[解決済み】JavaScriptの比較では、どちらの等号演算子(== vs ===)を使うべきですか?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】JavaScriptのgetElementByNameが機能しない
-
[解決済み] エラー。モジュールhtmlが見つからない
-
[解決済み】npm install --legacy-peer-deps は具体的に何をするのですか?どんなときに推奨されるのか/どんな使用例が考えられるのか?
-
[解決済み】XMLパースエラー:ルート要素が見つからない コンソールの場所 FF
-
[解決済み] ローカルファイルを開くことができません - Chrome: ローカルリソースのロードが許可されていません
-
[解決済み】このオブジェクトの "forEach "はなぜ関数でないのですか?
-
[解決済み】Syntax error: JavaScriptの不正なreturnステートメント
-
[解決済み】HTMLの最初の行に予期しないトークン<がある。
-
[解決済み】Javascript、[オブジェクトHTMLInputElement]を表示中。]
-
[解決済み] ループ内のJavaScriptクロージャ - シンプルな実用例