geek-logo.jpg

メモをとるのは面倒くさいし、検索するのも面倒くさい。散らかるブックマークも好きじゃない・・・そんな理由も何かにつながる

クロージャ

ここ最近、クロージャやら、即時関数やらを多様するようになってきた。
が、初歩的なミスを犯してしまったので、戒めとしてメモ。


例)Aタグのマウスオーバー時の色の変更(スタイルシートでいいじゃないか・・は言わないで)
下記のようなコードがあったとしよう。

var anchors = document.getElementsByTagName('a');
for( var i = 0, len = anchors.length; i < len; i++ ){
  var a = anchors[i];
  a.onmouseover = function()
  {
    a.style.color = '#ff0000';
  };
  a.onmouseout = function()
  {
    a.style.color = '#000';
  };
}

はい。これは問題なく動きます。
では、このコードを読み込み完了イベント内で書いてみると・・・

window.onload = function()
{
  var anchors = document.getElementsByTagName('a');
  for( var i = 0, len = anchors.length; i < len; i++ ){
    var a = anchors[i];
    a.onmouseover = function()
    {
      a.style.color = '#ff0000';
    };
    a.onmouseout = function()
    {
      a.style.color = '#000';
    };
  }
}

はい。失敗します。
これは、変数aはforループ内で都度初期化されているので、結果、最後に解釈されたAタグがonload内のローカル変数aの値となってしまいます。

結果は、ページ内どこのAタグをマウスオーバーしても、ページ内最後のAタグのみ色が変更されてしまうことになります。


そこでクロージャの登場です!!

window.onload = function()
{
  var anchors = document.getElementsByTagName('a');
  for( var i = 0, len = anchors.length; i < len; i++ ){
    var a = anchors[i];
    ( function(e)
    {
      e.onmouseover = function()
      {
        e.style.color = '#ff0000';
      };
      e.onmouseout = function()
      {
        e.style.color = '#000';
      };
    })(a);
  }
}


これで出来ました!!
何をしたかというと、forループ内に関数を作り、変数aをその関数内のローカル変数eへ渡してます。
このようにクロージャとは変数のスコープを切りたいときに利用したりできます。


JavaScriptを覚えるなら

よくわかるJavaScriptの教科書

新品価格
¥2,604から
(2013/12/1 15:56時点)