JavaScriptにおけるthisの詳細

2304 ワード

thisの指向
thisはjsで定義されたキーワードで、各関数領域に自動的に定義されていますが、その指向は人を混乱させます.実際の応用では、thisの指向は大きく分けて以下の4つの場合があります.
1.一般関数として呼び出す
関数が一般関数として呼び出されると、thisは全体のオブジェクトに向けられます.ブラウザでは、全体のオブジェクトはwindowです.
window.name = 'linxin';
function getName(){
    console.log(this.name);
}
getName();                   // linxin
この時、thisは全体の対象windowを指していることが分かります.ECMAScript 5の厳密なモードでは、この場合thisはグローバルオブジェクトに向けられないように規定されています.undefinedです.
'use strict';
function fun(){
    console.log(this);
}
fun();                      // undefined
2.対象となるメソッド呼び出し
関数がオブジェクト内のメソッドとして呼び出されると、オブジェクトにthisが向けられます.
var obj = {
    name : 'linxin',
    getName : function(){
        console.log(this.name);
    }
}

obj.getName();              // linxin
オブジェクトのメソッドに変数を割り当てると、この変数を呼び出します.
var obj = {
    fun1 : function(){
        console.log(this);
    }
}
var fun2 = obj.fun1;
fun2();                     // window
このときFn 2メソッドを呼び出してwindowオブジェクトを出力しましたが、このときthisはグローバルオブジェクトを指しています.fun 2に値を付けると、実際には相当します.
var fun2 = function(){
    console.log(this);
}
この時のthisはすでにobjとは関係がないことが分かります.このときfun 2は通常の関数として呼び出されます.
3.コンストラクタとして呼び出す
jsにはクラスがありませんが、コンストラクタからオブジェクトを作成し、new演算子を提供してコンストラクタを呼び出します.コンストラクタの外観は普通の関数と同じで、ほとんどの関数はコンストラクタとして使用できます.コンストラクタが呼び出されると,thisはこのコンストラクタの実用化されたオブジェクトを指す.
var Person = function(){
    this.name = 'linxin';
}
var obj = new Person();
console.log(obj.name);      // linxin
立体関数が明示的にオブジェクトを返すと、thisはオブジェクトを指します.
var Person = function(){
    this.name = 'linxin';
    return {
        name : 'linshuai'
    }
}
var obj = new Person();
console.log(obj.name);      // linshuai
この関数がnew呼び出しを用いずに普通の関数として実行されると、thisは依然として全体のオブジェクトを指す.
4.call()またはappy()呼び出し
関数のcall()またはappy()方法を呼び出して、thisの指向を動的に変えることができる.
var obj1 = {
    name : 'linxin',
    getName : function(){
        console.log(this.name);
    }
}
var obj2 = {
    name : 'linshuai'
}

obj1.getName();             // linxin
obj1.getName.call(obj2);    // linshuai
obj1.getName.apply(obj2);   // linshuai
この二つの方法はjsではよく使われています.次の記事を読むことができます.javascriptでは、apply、callの詳細が分かります.
もっと多い文章:lin-xin/blog