##thisとは何か?
thisは関数のスコープ内で有効な値で、実行中の関数を保持しているオブジェクトへの参照
例)
var cody = {
living : true,
age : 33,
gender : 'male',
getGender : function(){ return this.gender; }
};
console.log(cody.getGender()); //出力 : 'male'
##thisの値の決まり方
そんなthisの値は呼ばれた時のコンテクストに依存する。
例1)
var foo = 'fooA';
var myObject = { foo: 'fooB'};
var sayfoo = function(){
console.log(this['foo']);
}
//myObjectにsayfooメソッドをもたせ、その内容にsayfoo()関数を与える
myObject.sayfoo = sayfoo;
myObject.sayfoo(); //fooB
sayfoo(); //fooA
上記のコード例を実行すると、「オブジェクトを指定すると、そのオブジェクトがもつ'foo'が参照されるが、オブジェクトが指定されないと、グローバルなスコープでのfooが参照されること」がわかる。
例2)
また、入れ子関数内でthisを使用すると・・・
var myObject = {
func1: function(){
console.log(this);
var func2 = function(){
console.log(this);
var func3 = function(){
console.log(this);
}();
}();
}
}
myObject.func1();
結果
Object { func1: myObject.func1() }
Window → file:///C:/Users/hogehoge.html
Window → file:///C:/Users/hogehoge.html
入れ子関数内ではグローバルオブジェクトであるwindowを参照する
この問題を以下のように、スコープチェーンを使うことで解決できる
var myObject = {
myProperty: 'I can see the light',
myMethod: function(){
var that = this;
var helperFunction = function(){
console.log(that.myProperty);
console.log(this);
}();
}
}
myObject.myMethod();
結果
I can see the light
Window → file:///C:/Users/hogehoge.html
##thisの値をコントロールする
call()もしくはapply()を使うとthisの値をコントロールできる
var myObject = {}
var myFunction = function(pram1, pram2){
this.a = pram1;
this.b = pram2;
console.log(this);
}
myFunction.call(myObject, '1','2');//myObjectをthisとしてmyFunctionを呼ぶ
//myFunction.apply(myObject, ['1','2']);
//出力:Object { a: "1", b: "2" }
console.log(myObject);
//出力:Object { a: "1", b: "2" }
//*call(),apply()で関数を呼ぶ際に関数のスコープに設定されるthisの値がオーバーライドされることが確認できる。
##まとめ
・thisキーワードは、関数内で使用した場合、関数を保持するオブジェクトを参照する汎用的な手法である。
・thisの値は、関数が呼ばれたコンテクストに応じて関数の実行時に決定される。
・thisをグローバルスコープで使用すると、グローバルオブジェクトを参照する。
##リファレンス
開眼!JavaScript(第6章) (https://www.oreilly.co.jp/books/9784873116211/)