akkun_choi pedia
(1722 keywords)

よく使われているタグ

akkun_choiのお気に入り

  • さかずき。の辞書 さかずき。の辞書
  • 醤油辞典~うまいしょうゆ大好き!醤油マニア デイヴィッドのブック 醤油辞典~うまいしょうゆ大好き!醤油マニア デイヴィッドのブック
  • 西小倉事典 西小倉事典
  • 阿部道浩の【思いつくままに】百科 阿部道浩の【思いつくままに】百科

akkun_choi pediaのメンバー

  • akkun_choi akkun_choi
  • 西小倉パンデイロ 西小倉パンデイロ
  • tsucchon tsucchon
  • 須田健太郎 須田健太郎

引数束縛の履歴

複数の要素にイベントハンドラを追加したい場合、forで回したりするけど、関数オブジェクトをそのまま渡すとうまくいかない。

これは、関数の呼び出しがイベント追加時ではなく実行時に行われる(遅延評価)からである。下記の例では、event.addで追加した無名関数が参照してる変数iは、forループを終えた後(つまりi=10の時)のiである。

無名関数はイベントごとに別オブジェクトなだけど、中身のiはみな同じものを読でいる。

event = {
  events: [],
  add: function(event){
    this.events.push(event);
  },
  run: function(){
    for (var i = 0; i < this.events.length; i++){
      (this.events[i])();
    }
  }
};

for (var i = 0; i < 10; i++){
  event.add(function(){
    print(i + " " );
  });
}

event.run(); // 10 10 10 10 10 10 10 10 10 10 10




なので、無名関数が別々のiを参照してやればいい。
どうするか。別々のiを返すような関数を作成する。
下記の例では、一番上の方の無名関数は、引数iを与えるとそのiをprintするような関数を返す。

for (var i = 0; i < 10; i++){
  event.add(function(v){
    return function(){
      print(v + "\n");
    }
  }(i));
}

event.run(); // 0 1 2 3 4 5 6 7 8 9



カリー化は複数の引数をとる関数を変形して、1つの引数でその処理を行う関数を返す関数にすることで、ちょっと意味が違うみたい。カリー化が、この引数束縛の概念を利用しているのかな。