JavaScriptのthisとは何か
開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質
- 作者: Cody Lindley,和田祐一郎
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/06/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
thisとは
もっとも基本的な考え方は、
this
とは、関数を呼び出すオブジェクトへのリンク。this
とは、関数のスコープ内で有効な値で、実行中の関数をプロパティまたはメソッドとして保持しているオブジェクトへの参照である。
よって、実際にthis
が何を指しているかは、関数定義時ではなく、実行時のコンテキストに依存する。
// このfooはグローバルオブジェクトのスコープで定義 var foo = 'I am foo of global scope'; // このfooはmyObjectのプロパティ var myObject = { foo: 'I am myObject.foo' } var sayFoo = function() { console.log(this.foo); }; myObject.sayFoo = sayFoo; // グローバルスコープから実行 sayFoo(); // 出力: 'I am foo of global scope', thisはグローバルオブジェクト // myObjectのメソッドとして実行 myObject.sayFoo(); // 出力: 'I am myObject.foo', thisはmyObject
※ 私が確認したところJSFiddleでは上記が一部期待通りに動かない。以下の動作が原因のようだが。
var foo = 'foo'; console.log(this.foo); // JSFiddle上では、出力: undefined
call()やapply()で実行する場合
function.call(object, . . . )
やfunction.apply(object, [. . .])
の形でfunction
を実行した場合、
関数の呼び出し元は第一引数のobject
になる。
つまり、関数内のthis
が参照するのは、このobject
だ。
call()やapply()で関数を呼び出すと、その関数内の
this
が指すオブジェクトを自分で設定することができる。
var myObject = {}; var myFunction = function(param1, param2) { this.foo = param1; this.bar = param2; console.log(this); } // 出力: Window {..., foo: "foo", bar: "bar"…} myFunction('foo', 'bar'); // 出力: Object {foo: "foo", bar: "bar"} myFunction.call(myObject, 'foo', 'bar'); myFunction.apply(myObject, ['foo', 'bar']);
入れ子関数の中のthis
二つ以上の関数を入れ子にした場合、前述の基本に反した動作をするので注意が必要だ。
入れ子関数の中の
this
は、グローバルオブジェクトを参照する。
var myObject = { func1: function() { console.log(this); // 出力: myObject var func2 = function() { console.log(this); // 出力: window(グローバルオブジェクト) }(); } }; myObject.func1();
この仕様はECMAScript5で修正されるという記載があったが、 現時点Chromeで確認してもこの通りだっった。
※ OSX El Capitan 10.11.3, Google Chrome 51.0.2704.84 (Official Build) (64 ビット) で確認
コンストラクタ関数の場合
コンストラクタ関数内のthis
が何を指すかは、new
演算子を使って実行したか否かで変わる。
var Person = function(name) { this.name = name } // newあり。インスタンス生成 var bonnie = new Person('Bonnie Parker'); console.log(bonnie); // 出力: Person {name: "Bonnie Parker"} // new無し。ただの関数実行 var clyde = Person('Clyde Barrow'); console.log(clyde); // 出力: undefined console.log(window.name); // 出力: Clyde Barrow
new
でコンストラクタを実行した場合、インスタンスが生成される。
そして、コンストラクタ関数内のthis
はこの生成されたインスタンスである。
new
無しの場合、ただの関数呼び出しであるので、上記の場合だとthis
はグローバルオブジェクト(window)になる。
参考
開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質
- 作者: Cody Lindley,和田祐一郎
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/06/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る