JavaScriptでのthisはどのようにして呼ばれるかによって、それが指すものが決まる。
1. トップレベルコードで呼び出した場合はthisにはグローバルオブジェクトが渡される。
printf( this ); // [object global];
グローバルオブジェクトはただ一つ存在するもの。
グローバルスコープで代入した変数はグローバルオブジェクトのプロパティになる。
グローバルスコープで代入した関数はグローバルオブジェクトのメソッドになる。
var hoge = "fuga"; print( this.hoge ); // fuga var foo = function() { return 2; } print( this.foo() ); // 2
ブラウザではグローバルオブジェクトはWindowになる。
2. new式で呼ばれた関数内のthisはnewによって作成されたオブジェクトが渡される。
function Coffee( a_price ){ this.price = a_price; this.showprice = function() { print( this.price ); } } var myCoffee = new Coffee( 5 ); myCoffee.showprice(); // 5
3. new式を使わずに呼ばれた関数内のthisはグローバルオブジェクトが渡される。
function coffee( a_price ){ this.price = a_price; this.showprice = function() { print( this.price ); } } var myCoffee = coffee( 5 ); myCoffee.showprice(); // typein:54: TypeError: myCoffee is undefined
4. newを使わずに設定したオブジェクト内の関数を呼び出したときのthisはそれを含む最も内側のオブジェクトが渡される。
var cafe = { coffee: { price : 4, showprice : function(){ print( this.price ); } } }; cafe.coffee.showprice(); // 4
5. オブジェクトのメソッド内で代入した関数を呼び出した場合、その関数定義のthisにはグローバルオブジェクトが渡される。そのため、メソッド内で関数を代入する場合はvar that = thisというイディオムを使う。
var cafe = { get star() { return 3; }, show: function() { var that = this; print( that.star ); // 3 print( this.star ); // 3 var showsub = function () { print( that.star ); // 3 print( this.star ); // undefined }; showsub(); } } cafe.show();
6. 一つ前とほぼ同じですが、オブジェクトのメソッド内で定義した関数を呼び出した場合、その関数定義のthisにはグローバルオブジェクトが渡される。この場合もvar that = thisというイディオムを使う。
var cafe = { get star() { return 3; }, show: function() { var that = this; print( that.star ); // 3 print( this.star ); // 3 function f_showsub() { print( that.star ); // 3 print( this.star ); // undefined }; f_showsub(); } } cafe.show();
7. call/applyで使用した場合は分かりやすいので省略する。