背景: 暇なときに JS スコープ チェーンとクロージャに関する記事をいくつか読みましたが、以前に遭遇した問題に偶然気づきました。それは、for ループで dom ノードのイベント ドライバーを登録することです。を参照してください。詳細については、以下のコードを参照してください:
<!DOCTYPE html> <html> <head> <title>js闭包</title> <meta charset="utf-8" /> </head> <body> <button id="anchor1">1</button> <button id="anchor2">2</button> <button id="anchor3">3</button> <script type="text/javascript" src="jquery-1.12.1.js"></script> <script type="text/javascript"> function pageLoad(){ for (var i = 1; i <=3; i++) { var anchor = document.getElementById("anchor" + i); anchor.onclick = function () { console.log("anchor"+i); } } } window.onload = pageLoad; </script> </body> </html>
普通に考えれば、3つのボタンをクリックするとそれぞれ「anchor1」、「anchor2」、「anchor3」が表示されるはずですが、最初はそう思っていましたが、結果的にはどれも同じでした。ボタンをクリックすると、「anchor4」がプロンプト表示されます。
これはなぜですか?心配しないで、ゆっくり分析しましょう。js のスコープ チェーンとクロージャの知識が含まれるため、ここでは詳しく紹介しません。
まず、anchor.onclick について見てみましょう。これは、DOM レベル 0 のイベント ハンドラーです。私も知っています。このブロガーはサイコパスですか。私が言いたいのは、anchor.onclick< です。 🎜 >
は var name="Xiao Ming" と同様のイベント ハンドラーの宣言です。これは宣言されていますが、まだ実行されていません。ここで、上記の js コードを変更して見てみましょう。 🎜>
function pageLoad(){ for (var i = 1; i <=3; i++) { var anchor = document.getElementById("anchor" + i); anchor.onclick = function () { console.log("anchor"+i); } if(i==2){ debugger;//我们在这里debugger一下,然后在控制台手动触发#anchor1和#anchor2的点击事件 } } } window.onload = pageLoad;
ほら、デバッガーを使用して i==2 のときにループを停止し、次にコンソールに移動して #anchor1 と #anchor2 のクリック イベントを手動でトリガーすると、コンソールに「anchor2」が出力されます。
全体のロジックは大まかに次のようになります。anchor.onclick は常に i の参照を保存し、ループ中に i=1 から i=4 に変化し続けますが、anchor.onclick は一度保存されます。 「一度」という言葉)、
1、2、3の3通りありますが、最終的にiは4になるので、どのボタンをクリックしても「anchor4」が出力されます
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。