背景: 暇なときに JS スコープ チェーンとクロージャに関する記事をいくつか読んだのですが、以前遭遇した問題が for ループの Register イベントにあることに偶然気づきました。 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」が出力されます
結論: js におけるスコープチェーンとクロージャの知識は非常に重要です。ここでは触れませんでしたが、実は明確に説明されていないのではないかと心配しています。そしてそれは皆を誤解させるでしょう
JS クロージャーによって引き起こされるイベント登録の問題に関する上記の紹介は、エディターによって共有されたすべての内容です。参考にしていただければ幸いです。また、Script Home をサポートしていただければ幸いです。