1
2

More than 3 years have passed since last update.

JavaScriptにおけるthisの挙動について

Posted at

対象読者

  • JavaScriptのオブジェクトについて理解している初学者
  • thisの挙動がいまいちわからないJavaScript初学者

そもそもJavaScriptにおけるthisって何?

JavaScriptにおけるthisとは、自分自身を表すオブジェクトのことを挿します。重要なポイントは呼び出し元によって変わる点です。どういうことか以下に記載していきます。

グローバルオブジェクトを指すthis

sayFoo.js
const sayFoo = function () {
  console.log(this["foo"]);
}
foo = "foo";// 予約後であるconst,letをつけない場合はグローバルオブジェクトとして定義される
sayFoo();

sayFoo.jsでは、sayFoo()を呼び出した場合、グローバルオブジェクト(windowオブジェクト)として変数fooを宣言しています。よって、thisの対象はグローバルオブジェクトをさす挙動になっています。
this["foo"]の[]で書く方法はブラケット表記法と呼ばれる書き方です。
ブラケット表記法

インスタンス変数を指すthis①

sayFooInstance.js
const sayFoo = function () {
  console.log(this["foo"]);
}  
foo = 'foo';
const sayFooInstance = {
  foo: "I'm Instance Object",
  sayFoo
}
sayFooInstance.sayFoo();

sayFooInstance.jsでは、sayFooInstanceオブジェクトにて関数sayFooを呼び出しています。sayFooInstance内部からの呼び出しなので、this["foo"]foo: "I'm Instance Object"を参照しています。

インスタンス変数を指すthis②

myObjInstance.js
function MyObj(id) {
  this.id = id;
}
MyObj.prototype.printId = function (id) {
  console.log(this.id);
}
const newMyObj = new MyObj(5);
newMyObj.printId(2);// MyObjでidをthisに入れているため、2ではなく5と表示される

実行結果
スクリーンショット 2020-03-21 20.21.42.png

オブジェクトのプロトタイプに関数を定義して、実行しても、2が表示されず、5が表示されます。
なぜなら、MyObj関数をnewを使ってインスタンス化する際にthis.id = idで変数idをMyObj関数に代入しているため、printIdが実行されても、this.idの値に代入されないので、実行結果が5と表示されます。

ちなみに以下の様にClassを使っても同じ形になります。

インスタンス変数を指すthis③

myClass.js
class MyClass {
  constructor(id) {
     this.id = id;
  }
  print(id) {
    console.log(this.id);
  }
}
const myClass = new MyClass(5);
myClass.print(3);

実行結果
スクリーンショット 2020-03-21 20.21.42.png

コンストラクターを使ってインスタンス生成時にthis.idの値を代入します。
インスタンス変数を指すthis②でご紹介した通り、インスタンス生成時にthis.idにid値を代入しているため、実行結果は5と表示されます。

クラスについてはMDN Web docに記載があります。
クラス MDN Web doc

ちなみに、オブジェクト内部で関数を入れ子にした場合はどうなるでしょうか

インスタンス変数の内部で関数が入れ子になっている場合のthis

sayFooInstanceNest.js
const nestFunction = {
  nestFunc1: function () {
    console.log(this);// nestFunctionを参照
    const nestFunc2 = function () {
      console.log(this);// グローバルオブジェクトを参照
      const nestFunc3 = function () {
        console.log(this);// グローバルオブジェクトを参照
      }();
    }();
  }
}
nestFunction.nestFunc1();// 実行

実行結果は以下の画像の通り。
スクリーンショット 2020-03-21 19.14.17.png

入れ子にした場合のthisは、グローバルオブジェクトを参照します。

ちなみに以下の形{}();と書かれているコードをみて「ん?」と思った人もいると思います。
以下の書き方は即時実行関数式と呼ばれ、定義されるとすぐに実行されるJavaScriptの関数となります。

sokuji.js
const nestFunc3 = function () {
          ・・・中略・・・
}();// <= 波括弧の隣に丸括弧をつけることで、定義されるとすぐに実行される即時実行関数となります。

MDN Web Docs 用語集 IIFE (即時実行関数式)

thisは理解してしまえば、あとは応用が効く

内容に不備があったり、誤字脱字などあれば、コメントをいただければと思います。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2