Help us understand the problem. What is going on with this article?

JavaScriptにおけるthis

More than 3 years have passed since last update.

thisとは何か?

thisは関数のスコープ内で有効な値で、実行中の関数を保持しているオブジェクトへの参照

例)

var cody = {
  living : true,
  age : 33,
  gender : 'male',
  getGender : function(){ return this.gender; }
};

console.log(cody.getGender()); //出力 : 'male'

thisの値の決まり方

そんなthisの値は呼ばれた時のコンテクストに依存する。

例1)

var foo = 'fooA';
var myObject = { foo: 'fooB'};

var sayfoo = function(){
  console.log(this['foo']);
}

//myObjectにsayfooメソッドをもたせ、その内容にsayfoo()関数を与える
myObject.sayfoo = sayfoo;

myObject.sayfoo();  //fooB

sayfoo(); //fooA

上記のコード例を実行すると、「オブジェクトを指定すると、そのオブジェクトがもつ'foo'が参照されるが、オブジェクトが指定されないと、グローバルなスコープでのfooが参照されること」がわかる。

例2)
また、入れ子関数内でthisを使用すると・・・

var myObject = {
  func1: function(){
      console.log(this);
      var func2 = function(){
        console.log(this);
        var func3 = function(){
            console.log(this);
        }();
      }();
    }
}

myObject.func1();

結果

Object { func1: myObject.func1() }
Window → file:///C:/Users/hogehoge.html
Window → file:///C:/Users/hogehoge.html

入れ子関数内ではグローバルオブジェクトであるwindowを参照する

この問題を以下のように、スコープチェーンを使うことで解決できる

var myObject = {
  myProperty: 'I can see the light',
  myMethod: function(){
    var that = this;
    var helperFunction = function(){
      console.log(that.myProperty);
      console.log(this);
    }();
  }
}

myObject.myMethod();

結果

I can see the light
Window → file:///C:/Users/hogehoge.html

thisの値をコントロールする

call()もしくはapply()を使うとthisの値をコントロールできる

var myObject = {}

var myFunction = function(pram1, pram2){
  this.a = pram1;
  this.b = pram2;
  console.log(this);
}

myFunction.call(myObject, '1','2');//myObjectをthisとしてmyFunctionを呼ぶ
//myFunction.apply(myObject, ['1','2']);
//出力:Object { a: "1", b: "2" }


console.log(myObject);
//出力:Object { a: "1", b: "2" }
//*call(),apply()で関数を呼ぶ際に関数のスコープに設定されるthisの値がオーバーライドされることが確認できる。

まとめ

・thisキーワードは、関数内で使用した場合、関数を保持するオブジェクトを参照する汎用的な手法である。

・thisの値は、関数が呼ばれたコンテクストに応じて関数の実行時に決定される。

・thisをグローバルスコープで使用すると、グローバルオブジェクトを参照する。

リファレンス

開眼!JavaScript(第6章) (https://www.oreilly.co.jp/books/9784873116211/)

Knbass
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away