Pebble Coding

ソフトウェアエンジニアによるIT技術、数学の備忘録

JavaScriptでthisに渡されるもの

JavaScriptでのthisはどのようにして呼ばれるかによって、それが指すものが決まる。

1. トップレベルコードで呼び出した場合はthisにはグローバルオブジェクトが渡される。

printf( this ); // [object global];

グローバルオブジェクトはただ一つ存在するもの。
グローバルスコープで代入した変数はグローバルオブジェクトのプロパティになる。
グローバルスコープで代入した関数はグローバルオブジェクトのメソッドになる。

var hoge = "fuga";
print( this.hoge ); // fuga
var foo = function() { return 2; }
print( this.foo() ); // 2

ブラウザではグローバルオブジェクトはWindowになる。


2. new式で呼ばれた関数内のthisはnewによって作成されたオブジェクトが渡される。

function Coffee( a_price ){
      this.price = a_price;
      this.showprice = function() {
          print( this.price );
      }
}
var myCoffee = new Coffee( 5 );
myCoffee.showprice(); // 5


3. new式を使わずに呼ばれた関数内のthisはグローバルオブジェクトが渡される。

function coffee( a_price ){
    this.price = a_price;
    this.showprice = function() {
        print( this.price );
    }
}
var myCoffee = coffee( 5 );
myCoffee.showprice(); //  typein:54: TypeError: myCoffee is undefined


4. newを使わずに設定したオブジェクト内の関数を呼び出したときのthisはそれを含む最も内側のオブジェクトが渡される。

var cafe = {
    coffee: {
        price : 4,
        showprice : function(){
            print( this.price );
        }
    }
};
cafe.coffee.showprice(); // 4


5. オブジェクトのメソッド内で代入した関数を呼び出した場合、その関数定義のthisにはグローバルオブジェクトが渡される。そのため、メソッド内で関数を代入する場合はvar that = thisというイディオムを使う。

var cafe = {
    get star() { return 3; },
    show: function() {
        var that = this;
        print( that.star ); // 3
        print( this.star ); // 3
        var showsub = function () {
            print( that.star ); // 3
            print( this.star ); // undefined
        };
        showsub();
    }
}
cafe.show();


6. 一つ前とほぼ同じですが、オブジェクトのメソッド内で定義した関数を呼び出した場合、その関数定義のthisにはグローバルオブジェクトが渡される。この場合もvar that = thisというイディオムを使う。

var cafe = {
    get star() { return 3; },
    show: function() {
        var that = this;
        print( that.star ); // 3
        print( this.star ); // 3
        function f_showsub() {
            print( that.star ); // 3
            print( this.star ); // undefined
        };
        f_showsub();
    }
}
cafe.show();


7. call/applyで使用した場合は分かりやすいので省略する。