ここでは、JavaScriptにおけるthisキーワードの基本的な使い方について説明します。
thisは何を参照しているのか
thisの値は、呼び出される際のコンテクストに依存して決まります。
1. 関数・メソッド内での呼び出し
2. コンストラクタ内での呼び出し
3. apply,callでの呼び出し
1. 関数・メソッド内での呼び出し
関数・メソッドで呼び出されるthisキーワードは、その関数・メソッドをプロパティとして持つオブジェクトへの参照です。
さらに、関数オブジェクト内での呼び出しと、オブジェクトのメソッド内での呼び出しの2つに分けて考えることができます。
オブジェクトのメソッド
thisを含む関数がオブジェクトのプロパティとして(メソッドとして)呼ばれた場合、thisはそのオブジェクトを参照します。
1 2 3 4 5 6 7 8 |
var obj = { greet: "hello", say: function(){ console.log(this.greet); } }; obj.say();//helloと表示 |
上記の場合、thisはobjを参照しており、this.greetはobj.greetとなるので、say()メソッドを実行すると「hello」と表示されます。
関数オブジェクト
また、thisを含む関数がグローバルスコープで呼ばれた場合、thisはグローバルオブジェクトを参照します。次の例を見てみましょう。
1 2 3 4 5 6 7 |
var hello = "Hello"; var greet = function(){ console.log(this.hello); }; greet(); //Hello(window.helloと同義) |
グローバルスコープの関数・変数は、windowオブジェクトのプロパティとして登録されます。そのため、greet()関数をグローバルスコープで(単に関数として)呼び出した場合、thisはgreet()をプロパティとして持つwindowオブジェクトを参照します。
つまり、この文脈でのthis.helloはwindow.helloと同義となり"Hello"が表示されます。
メソッドと関数ではthisが参照するオブジェクトは異なりますが、呼び出し元の関数をプロパティとしてオブジェクトを参照するという点では同じです。
2. コンストラクタ関数内でのthis
インスタンスを生成する際にnew演算子を伴ってコンストラクタが呼ばれる時、コンストラクタ内のthisは新たに生成されるインスタンスを参照します。
1 2 3 4 5 6 7 8 9 |
//コンストラクタ var Person = function(name, age){ this.name = name; this.age = age; }; //インスタンス生成 var taro = new Person("Taro", 21); console.log(taro.name); //Taro |
Personのインスタンスを生成する際、コンストラクタが受け取った引数name, ageの値をthis.name, this.ageに登録しています。
ここでのthisは生成されるインスタンスであるtaroを参照しているため、登録された値をインスタンス(taro)のプロパティとして利用することができます。
3. apply,callでの呼び出し
上記の2つとは全く異なるやや例外的なパターンが、apply, callでの呼び出しです。このメソッドを使うと、thisの参照先を任意のオブジェクトに変更することができます。
1 2 3 4 5 6 7 8 9 10 11 12 |
var obj = { greet: "hello", say: function(){ console.log(this.greet); } }; var jaObj = { greet: "こんにちは", }; obj.say.apply(jaObj); // こんにちは |
上記の例では、obj.sayメソッド内のthisの参照先をobjからjaObjに変更しています。つまり、this.greetはjaObj.greetを参照しているので、「こんにちは」と表示されます。