今更聞けない JavaScript の挙動

非常に恥ずかしい勘違いをしていたのでメモとして残しておきます。jQuery を使って li タグに click イベントをバインドする時に、次のようなコードを記述してみます。

$(document).ready(function() {
  var i = 0;
  $("li").each(function() {
    alert(i);
    $(this).click(function() {
      alert(i);
    });
    i ++;
  });
});

上のコードを実行すると、ロード完了時には 0, 1, 2... と変数が加算されていくに従って変化した値がアラートで出力されます。一方で、それぞれの li タグをクリックした時の値はすべて i の値が変化した後の最終値がアラートで出力されてしまいます。

では、どうすれば実行中の値を残しておけるかと言うと、以下のようにコードを変更します。

$(document).ready(function() {
  var i = 0;
  $("li").each(function() {
    alert(i);
    $(this).bind("click", {index: i}, function(event) {
      alert(event.data.index);
    });
    i ++;
  });
});

実行中の値をバインドされた無名関数の引数にした Event オブジェクトに渡しておく事で、該当するオブジェクトの data プロパティに値を保存しておく事ができます。