DATE : 2006/08/08 (Tue)
以前の記事では、this キーワードの指すオブジェクトは、関数の呼び出しを行うオブジェクトによって異なるということを書きました。
しかし、Protptyoe.js にある bind メソッドを使用すると、this キーワードが指すオブジェクトを指定することができます。
例えば、次のコードは、printMthod 関数内では this キーワードの指すオブジェクトがないために undefined と画面に表示されます。
function MyObject {
this._field = 1;
}
MyObject.prototpye.printField = function() {
document.write(this._field);
}
var myObject = new MyObject();
var printMethod = myObject.printField;
printMethod();
しかし、Prototype.js によって、Function オブジェクトに追加された bind メソッドを使用すると、this の指すオブジェクトを指定することができます。
function MyObject {
this._field = 1;
}
MyObject.prototpye.printField = function() {
document.write(this._field);
}
var myObject = new MyObject();
var printMethod = myObject.printField.bind(myObject);
printMethod();
結果は、「1」と表示されます。
bind メソッドのソースコードを覗くと、次のようになっています。
Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}
これは、Prototype.js 1.4 の bind メソッドです。
この中で、$A 関数は引数を配列に変換する関数、shift メソッドは、配列の初めの要素を取り出す(その後、空いた部分を詰める)メソッドです。
__method 引数には、bind メソッドを呼び出したオブジェクト(つまり、上の例では printField 関数)が格納されます。そして、object には、bind メソッドの第1引数(上の例では、myObject)が渡されます。
そして戻り値として、bind メソッドを呼び出した関数オブジェクトを実行する関数を生成しています。この関数の中では、Function オブジェクトの apply メソッドが使用されています。apply メソッドは、呼ばれた関数オブジェクトを実行するメソッドで、第1引数に this キーワードの指すオブジェクト、第2引数に引数を格納した配列を格納することになっています。
こうすることで、this キーワードが指し示すオブジェクトを指定できるようになっています。
なお、Function オブジェクトの apply メソッドは、ECMAScript の仕様に定義されています。つまり、Prototype.js を使わずに、apply メソッドを使うという手もあります。