↓エラーパターン
$(function() { var data = [ {label:'リンク1', value:1}, {label:'リンク2', value:2}, {label:'リンク3', value:3}, {label:'リンク4', value:4}, {label:'リンク5', value:5} ]; var ul = $('<ul/>'); for(var i = 0, l = data.length; i < l; i++) { var item = data[i]; var li = $('<li/>').text(item.label).click(function(e) { console.log(e.type, item.value); }); ul.append(li); } $('body').append(ul); });
↓正しいパターン
$(function() { var data = [ {label:'リンク1', value:1}, {label:'リンク2', value:2}, {label:'リンク3', value:3}, {label:'リンク4', value:4}, {label:'リンク5', value:5} ]; var ul = $('<ul/>'); for(var i = 0, l = data.length; i < l; i++) { var item = data[i]; var li = $('<li/>') .text(item.label) .click( function () { //エンクロージャ var closureItem = item; return function(e) { //クロージャ console.log(e.type, closureItem.value); }; }() ); ul.append(li); } $('body').append(ul); } );
jQueryで動的にリストを作ってli要素をクリックしたときにコンソールに出力する(例えばリンク1をクリックしたら「click1」と表示する)サンプルで、エラーパターンは、どれをクリックしても「click 5」と表示されてしまう、それに対して正しいパターンはリンク1→click1,リンク2→click2,・・・という風に正しく動作する、というものです。
一応クロージャの基礎は勉強したので、クロージャからclosureItem変数を参照できる、というのはわかるのですが、なぜ正しいパターンなら正しく動くのかがいまいちはっきりしません。
そのサイトの解説では、エラーパターンは「初期処理を終えた時点の変数itemにdata[4]が代入されている、そこでクリックすることになるのでどこをクリックしてもclick5と表示される。」とあり、それはそれで理解できます(つまりくり返し処理後にクリックということ。)ただそれは正しいパターンでも同じなのではないか?よって正しいパターンでも常にclick5が表示されるのではないか?と思ってしまいます。(実際は正しいパターンは正しく動く。)
なぜここでクロージャを使うとリンク1→click1,リンク2→click2,・・・というような結果になるのでしょうか?
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。