※ ここで示すいくつかの例は "use strict"; を想定していません!
this の実体は 変数
this の実体は「何かしらのオブジェクトを参照」している「読み込み専用」の「変数」だよ。読み込み専用なので代入できないよ
this = 5;
// ReferenceError: Invalid left-hand side in assignment
どのオブジェクトを参照しているか
「何かしらのオブジェクト」ということは、とりあえず、typeof で "object" になるものを参照するっていう認識でおk
そして、何のオブジェクトを参照しているかはコンテキストに応じて変化するよ。参照には一定の規則があって、関数外(トップレベル)か関数内(ローカル)かで大きく変わるよ。
関数外であるグローバルな空間での this
Webブラウザでの実行を想定した場合、this はグローバルな空間で Window オブジェクトを参照
console.log(this);
// Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
関数内では 関数の呼び出し方法 で参照先オブジェクトが変わる
関数の呼び出し方法で変わるっていうことは、実行時に this がセットされていくということで、4種類の呼び出しパターンがある。
関数内での this
前提:オブジェクトのプロパティである function はメソッド、そうでない場合は関数として呼び分けるよ(グローバルな空間に定義した関数は実は window オブジェクトのプロパティの1つだったりもするけど)
// メソッドを持つオブジェクト
var myObj = {
value: "Hello World",
greet: function(){
console.log(this.value);
}
};
myObj.greet();
// Hello World
// 関数
var hoge = function()
{
console.log("hoge");
}
window.hoge(); // window は省略可能
// hoge
関数内での this は グローバルオブジェクト がセットされるよ。ブラウザを想定すると Window オブジェクト。
(function(){
console.log(this);
}());
// Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
メソッド内での this
メソッド内では、そのオブジェクトがセットされるよ。この例でいうと myObj
// メソッドを持つオブジェクト
var myObj = {
myObjFunc: function(){
console.log(this);
}
};
myObj.myObjFunc();
// Object {myObjFunc: function}
コンストラクタ内での this
コンストラクタ内での this は new によって生成したオブジェクトを参照するよ。この例でいうと myHoge オブジェクト
var Hoge = function(huga)
{
this.huga = huga;
}
var myHoge = new Hoge("chrowa3");
console.log(myHoge);
apply( ) や call( ) で 好きなオブジェクトへの参照をセット
call( ) や apply ( ) は 他のオブジェクトが持つメソッドをさぞ自分のメソッドかのように呼び出すメソッドだよ
この例では、Hoge( ) を new することで生成された myHoge オブジェクトを this としてセットしている。
var Hoge = function(){};
Hoge.prototype.hogeFunc = function(){return this;};
var Huga = function(){};
Huga.prototype.hugaFunc = function(){return this;};
var myHoge = new Hoge();
Huga.prototype.hugaFunc.call(myHoge);
// Hoge {hogeFunc: function}
myHoge オブジェクトで Huga の hugaFunc() を call() しているよ。
hugaFunc() の処理は this を return で返しているだけなんだけど、this が myHoge でセットされているので 結果的に Hoge オブジェクトが返ってきている。
(番外編) イベントハンドラ(メソッド)内での this
まず HTML ね
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>this!</title>
<script src="this.js"></script>
</head>
<body>
<p><a id="lnk" href="#">click</a></p>
</body>
</html>
続いて js
window.onload = function()
{
var printThis = function()
{
console.log(this);
};
document.getElementById("lnk").onclick = printThis;
};
// <a id="lnk" href="#">click</a>
イベントハンドラ(メソッド)内での this は イベントが発生した元の要素を参照するよ
以上、this のざっペロでした