goo blog サービス終了のお知らせ 

DEVELOPMENTOR*LEARNING RESOURCE LAB.

ソフトウェア開発現場の視点からソフトウェアと開発者の価値を高める「ホットな何か」をお届けします。(休止)

Function.applyを知ればprototype.jsのFunction.bindを理解できる

2006年10月05日 | prototype cast
[ajax] prototype.jsの活用にはFunction.applyがどう振舞うか知っておきたいの続きです。prototype.jsを使ったコードではfunctionを指定した繰返しの構文をよく見かけます。

次の例はNumber.timesを使って2の8剰を計算し、その結果を「this.v」に保存しています。もちろん結果は256です。
var Foo = Class.create();
Foo.prototype = {
  initialize: function() {
    this.v = 1;
  },
  f1: function() {
    (8).times(function() {
      this.v *= 2;
    }.bind(this));
    alert('Are you ready?: '+this.v);
  }
}

var foo = new Foo();
foo.f1();



前述の例ではfunction{・・・}.bind(this)という馴染みのない構文を使っています。この「.bind(this)」とはどんな意味があるのでしょうか。これからその意味を確かめてみます。

前述の例から「.bind(this)」を削除してみます。結果は256と思いきや1になります。とても結果が1になるようには見えません。
var Foo = Class.create();
Foo.prototype = {
  initialize: function() {
    this.v = 1;
  },
  f1: function() {
    (8).times(function() {
      this.v *= 2;
    });
    alert('Are you ready?: '+this.v);
  }
}



前述の例を別の書き方で表現すると次のようになります。書き方を変えると結果が256でなく1になるのが当然とわかります。
function g1() {
  this.v *= 2;
}
var Foo = Class.create();
Foo.prototype = {
  initialize: function() {
    this.v = 1;
  },
  f1: function() {
    (8).times(g1);
    alert('Are you ready?: '+this.v);
  }
}



前述の例に「.bind(this)」を加えてみます。結果は1でなく256になります。Function.bindの振る舞いとその効果が見えてきましたね。
function g1() {
  this.v *= 2;
}
var Foo = Class.create();
Foo.prototype = {
  initialize: function() {
    this.v = 1;
  },
  f1: function() {
    (8).times(g1.bind(this));
    alert('Are you ready?: '+this.v);
  }
}



次の関数(メソッド)はFunction.bindのソースコードを抜粋したものです。bindは新しいfunctionを生成しています。生成したfunctionは自functionをFunction.applyを使って実行しますが、そのときbindの引数を指定しています。この引数は前述の例では「this」に相当します。
Function.prototype.bind = function() {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }
}


[ajax] prototype.jsの活用にはFunction.applyがどう振舞うか知っておきたいを振り返りながら読み取ってください。Function.bindの理解が深まり、prototype.jsの活用の幅が広がります。

最新の画像もっと見る