KZKY memo

自分用メモ.

javascriptにおけるthis

jQueryをすこし触れたことがあるだけで,js自体は全然書けないので最近ちょくちょく勉強中.
そこで,thisに関して???だらけだったので,メモ.

オブジェクトの中で定義された関数の中で関数を定義して,その関数をいろいろなコンテキストで呼ぶことによって,thisが何を指すのかを検証.

name = "first global variable"
var obj = {
    name: "hogehoge",
    hello : function(){
	that = this;

	var name = "variable in hello"; // localのname
	var hello2 = function(){	    
	    print("in hello2: " + that.name) // thatは呼び出しもとによって決まる
	    print("in hello2: " + this.name) // thisは呼び出しもとによって決まる.
	    print("in hello2: " + name) // nameはローカル変数を指している.
	    print("in hello2: " + this)
	    print("in hello2: " + that)
	    print("")
	};
	// thisが使用されている関数と並列なスコープで呼び出し.
	// hello2はメソッドとしてではなく関数として呼び出されているから
	// thisはglobalになる.
	print("- thisが使用されている関数と並列なスコープで呼び出し.-")
	hello2();
	return hello2;
    }
};

// globalスコープから呼び出し
print("--- hello2を受け取る. ---")
var _hello2 = obj.hello() // thatはobjを指すことになる

// globalスコープから呼び出し
name = "second global variable"
print("--- globalスコープからhello2を呼び出し ---")
_hello2() 

// obj2を作る.
var obj2 = {
    name : "hogehoge2",
}

// obj2から呼び出し.
print("--- obj2からhello2を呼び出し. ---")
obj2.hello2 = _hello2;
obj2.hello2();

// objからhelloを読んで,globalスコープからhello2を呼ぶ.
print("--- objからhelloをよんで,globalスコープからhello2を呼ぶ. ---")
obj.hello()(); 

実行結果.

--- hello2を受け取る. ---
- thisが使用されている関数と並列なスコープで呼び出し.-
in hello2: hogehoge
in hello2: first global variable
in hello2: variable in hello
in hello2: [object global]
in hello2: [object Object]

--- globalスコープから呼び出し ---
in hello2: hogehoge
in hello2: second global variable
in hello2: variable in hello
in hello2: [object global]
in hello2: [object Object]

--- obj2から呼び出し. ---
in hello2: hogehoge
in hello2: hogehoge2
in hello2: variable in hello
in hello2: [object Object]
in hello2: [object Object]

--- objからhelloを読んで,globalスコープからhello2を呼ぶ. ---
- thisが使用されている関数と並列なスコープで呼び出し.-
in hello2: hogehoge
in hello2: second global variable
in hello2: variable in hello
in hello2: [object global]
in hello2: [object Object]

結局,thisは実行時に決定される.
ただし,

関数がメソッドではなく関数として呼び出された場合、
thisキーワードはグローバルオブジェクトを参照します。
ややこしいことに、メソッドとして呼び出された関数内に入れ子にされた
別の関数が関数として呼び出された場合も、グローバルオブジェクト
を参照します。

らしい.