つまずきやすいJavaScriptのthisの挙動を図解で理解する

JavaScriptを学び始めた多くの人が「this」の挙動に混乱します。同じ「this」でも、どこで使うかによって参照する対象が変わるからです。この記事では、「this」が何を指すのかを図解と具体例でわかりやすく解説します。

Case 1: 通常関数をnewなしで実行した時のthis

関数を new を使わずに通常の関数として実行した場合、this はグローバルオブジェクト(ブラウザでは window、Node.jsでは globalを指します。これは strict モードでない場合のデフォルトの挙動です。

strict モード('use strict')が有効な場合は、thisundefined になります。

function User(name) {
  this.name = name;
  console.log(this);
  // → window(ブラウザ)または global(Node.js)
}

User('Taro'); // newなし

Case 2: 通常関数をnewありで実行した時のthis

通常の関数も、new をつけて呼び出すことで「コンストラクタ関数」として振る舞います。このとき、this は自動的に新しく生成されたオブジェクトを指します。

function User(name) {
  this.name = name;
  console.log(this);
  // → User { name: 'Taro' }
}

const u = new User('Taro'); // newあり

Case 3: アロー関数内でのthis

アロー関数は自分自身の this を持たず、定義されたスコープ(外側)の this をそのまま使います。オブジェクトのメソッドとして使った場合でも、そのオブジェクトは参照されず、意図しない動作になることがあります。

const obj = {
  name: 'Hanako',
  greet: () => {
    console.log(this.name);
    // → undefined(外側スコープのthisを継承)
  }
};

obj.greet();

アロー関数では、定義された時点のthisをそのまま使うという点がポイントです。

Case 4: オブジェクトリテラルのメソッド内でのthis

オブジェクトリテラルの中に定義されたメソッドでは、this はそのオブジェクト自身を参照します。これはオブジェクトリテラル形式で定義されたメソッドによく見られる挙動です。

const user = {
  name: 'Taro',
  greet: function() {
    console.log(this.name); // → "Taro"
  }
};

user.greet();

Case 5: コンストラクタ関数のメソッド内でのthis

自作オブジェクトのコンストラクタ関数を new を使って呼び出すと、this は新しく生成されたインスタンスを指します。コンストラクタの中で this にプロパティを定義することで、生成されたオブジェクトに状態や機能を与えることができます。

これは Case 2 と同じ仕組みで、通常の関数が new を使って呼ばれたときの挙動です。つまり、JavaScriptでは関数自体がオブジェクトであり、関数オブジェクトは new によってインスタンス化可能な「コンストラクタ」として振る舞うことができます。

function User(name) {
  this.name = name;
  this.greet = function() {
    console.log(this.name); // → "Ichiro"
  };
}

const user = new User('Ichiro');
user.greet();

[ 補足 ] 明示的にthisを指定する:call, apply, bind

JavaScriptでは、関数のthisは呼び出し方に応じて決まりますが、callapplybindといったメソッドを使うことで意図的にthisを指定することが可能です。これにより、関数を別のコンテキストで再利用したい場合や、コールバック関数でthisを明示したい場面で役立ちます。

メソッド実行タイミング引数の渡し方戻り値thisの設定
call即時カンマ区切り関数の戻り値
apply即時配列で渡す関数の戻り値
bind遅延(新関数返す)カンマ区切り新しい関数
function greet() {
  console.log(this.name);
}

const user = { name: 'Mika' };

greet.call(user); // → "Mika"

まとめ:thisは「関数の呼ばれ方」で決まる

JavaScriptの「this」は、その関数が「どのように呼ばれたか」で決まります。アロー関数、メソッド、コンストラクタなど、呼び方によって変わるので、図解と実行結果をセットで確認することで理解が深まります。とは言いつつも、特にCase1とCase3のイメージさえ出来ていればthisの挙動で悩まされることはないはずです。

Contact

ウェブサイトの制作や運用に関わる
お悩みやご相談
お気軽にお問い合わせ下さい

ウェブサイトと一口に言っても、企業サイトやECサイト、ブログ、SNSなど、その“カタチ”は目的に応じてさまざまであり、構築方法や使用する技術も大きく異なります。株式会社コナックスでは、お客様のご要望やブランドの個性を丁寧に汲み取り、最適なウェブサイトの“カタチ”をご提案いたします。

デザイン、ユーザビリティ、SEO対策はもちろん、コンテンツ制作やマーケティング戦略に至るまで、あらゆるフェーズでお客様のビジネスに寄り添い、成果につながるウェブサイトづくりをサポートいたします。私たちは、ウェブサイトの公開をゴールではなくスタートと捉え、お客様のビジネスの成功に向けて共に伴走してまいります。