いつの間にかクロージャを使えるようになったっぽい件

なんか、ふとしたはずみで使えちゃったので、分かったうえで書いた(はずの)コードを3種類貼ってみます。
ひよこつつきゲームに出てくるコードです。

アハ体験のきっかけはこの動画です。途中でサラッとクロージャが出現します。

スポンサーリンク

ヒット数カウンター

よく例示されているような、関数を返す関数です。
関数内で定義した変数countを、返した関数によってインクリメントしていきます。

var initHitCounter = function(){
  var count = 0;
  var counter = document.getElementById("hit-count");
  counter.textContent = 0;
  return function(){
    count++;
    counter.textContent = count;
    return count;
  };
};
var hitCount = initHitCounter();

ひよこをつついた時に、hitCount関数を呼び出すと、countが一つ増えます。
再代入するとリセットされます。

スコアカウンター

関数を返す関数の発展形。
単純なインクリメントじゃない事もできました。

scoreCalcに渡す変数の種類(=キャラクターの種類)によって、加算されるスコアが変わります。

var initScore = function(){
  var score = 0;
  var lastScore = 1;
  var view = document.getElementById("score");
  view.textContent = 0;
  return function(type){
    switch(type){
      case "piyo":
        lastScore = 1;
        break;
      case "food":
        lastScore = lastScore * 2;
        break;
      //~~省略(全ての種類についてスコアを設定)
      default:
        return;
    }
    score += lastScore;
    view.textContent = score;
    return score;
  };
};
var scoreCalc = initScore();

ヒット時動作を付与する仕組み

こちらはちょっと複雑かも。
ヒヨコを出現させる関数内で、ヒヨコにオンクリックの動作を付与する部分です。
これは完全に冒頭の動画からひらめきました。

関数内にさらにスコープ(の代わりの即時関数)を作って、変数をトラップしています。
こうすると、次のヒヨコを出現させる時に、同じ関数を呼んでも、いちどトラップした変数_idは影響を受けません。

//ヒヨコ出現メソッド
var appear = function(actor, n){
  //~~省略(出現座標を決める)

  //表示する要素を作る
  var piyo = document.createElement('div');
  piyo.id = n;
  //~~省略(piyoのstyleを設定)
  (function(){
    var _id = n;
    piyo.onclick = function(){hitfunction(_id);};
  })();
  field.appendChild(piyo);

  //~~省略(出現アニメーションをセット)
};

(ここでは値そのものをトラップしてますが、参照渡しのもの(配列とか)は、たぶんトラップしても意味ないので気をつけましょう)

余談

というわけで、クロージャ3パターンでした。
 

ところで、仮完成してテストプレイしてると、どうもフリーズすることがあるので、コードの挙動を詳しく調べてみました。
クロージャの使い方が悪いと、循環参照やらメモリリークやら起きるらしいんですが、スクリプト自体は循環参照には陥っていないようでした。

そうではなく、ひよこを無限に生成していることで、クラッシュしてた模様。(上記のひよこ出現メソッド)
DOM上から要素を剥がせば、勝手に破棄されると思ってましたが、そうでもないらしい。(←良く分かってない)
このへんクロージャのせいなのか、他の要因か分かりませんが、とりあえず生成するDOM要素を有限個に制限したら、固まらなくなったようです。

ふう。

あとがき

クロージャって自転車に乗るようなもので、説明文を読んでも分かるような分からんような感じです。
使えるようになって初めて「そうか!」ってなります。

と、どっかのサイトに書いてあったんですが、まさにその通りでした。

面白い、けどまだまだ奥が深い・・・!

そんなとこでした。

コメント

スポンサーリンク