JavaScriptのコードを読んでいると頻繁に登場する this というキーワード。「なんとなく自分自身を指しているのだろう」と理解していても、コードの書き方や実行する場所によって中身がコロコロと変わるため、多くの開発者を悩ませる原因になっています。
モダンなフロントエンド開発(Reactのクラスコンポーネント、Web APIsのイベントリスナ、オブジェクト指向のクラス設計など)において、this の正確な理解はバグを未然に防ぐために不可欠です。本記事では、this の本質から、実務で絶対に押さえるべきポイントまでを分かりやすく解説します。
JavaScriptのthisとは?
まずは最も重要な結論からお伝えします。
結論:thisとは何か?
JavaScriptのthisとは、一言で言えば「その処理を実行している『自分自身(オブジェクト)』」を指す特殊な変数です。
ただし、thisを難しくしている最大の理由は以下にあります。
- thisが何を指すかは、コードを書いた場所ではなく、「どうやって呼び出されたか(実行時の状況)」によって動的に変わる。
固定の値を指すわけではないからこそ、多くの人が「thisが何を指しているのか分からない」という壁にぶつかるのです。
まずは「this=今の持ち主」と考えよう
動的に変わるthisを直感的に理解するために、まずは「this = その関数(メソッド)を動かしている『今の持ち主』」というイメージを持ってください。
例えば、以下のようなシチュエーションを考えてみましょう。
あなたが友人と話しているとき、自分のスマホを指して「これ(this)、最近買ったんだ」と言えば、それは「あなたのスマホ」を指します。 しかし、友人が自分のスマホを取り出して「じゃあ、**これ(this)**は?」と言った場合、同じ「これ(this)」という言葉でも、指している対象は「友人のスマホ」に変わります
プログラミングにおけるthisもこれと全く同じです。
- userA.showName() と呼び出されたなら、thisの持ち主はuserAです。
- userB.showName() と呼び出されたなら、thisの持ち主はuserBに切り替わります。
「誰がその処理を呼び出しているのか」に注目することが、this をマスターする最大の秘訣です。
オブジェクトで使うthis(基本編)
thisの最も基本であり、実務でも頻出するパターンが「オブジェクトのメソッド内での使用」です。
thisで自分のデータを取得できる
オブジェクトの中に定義した関数(メソッド)の中でthisを使うと、そのオブジェクト自身が持つプロパティ(データ)にアクセスできます。
const user = {
name: "田中",
age: 26,
greet: function() {
// thisは「今の持ち主」であるuserオブジェクトを指す
console.log(`こんにちは、${this.name}です。`);
}
};
user.greet(); // 出力: こんにちは、田中です。
なぜわざわざ「this」を使うの?
ここで一つの疑問が浮かびます。「this.nameなんて書かずに、user.nameと直接書けばいいのではないか?」という疑問です。
// thisを使わない書き方
const user = {
name: "田中",
greet: function() {
console.log(`こんにちは、${user.name}です。`); // これでも動くが…
}
};
確かにこれでも動作しますが、実務の設計においてこの書き方は推奨されません。thisを使うことには、強力な2つのメリットがあるからです。
メリット1:オブジェクト名の変更に強い(堅牢性)
もしシステムの都合で、変数名をuserからmemberに変更しなければならなくなった場合、thisを使っていれば内部のコードを書き換える必要はありません。しかし、直接user.nameと書いていると、内部の記述もすべて手作業で書き換える必要があり、修正漏れによるバグ(タイポ)の原因になります。
メリット2:関数を再利用できる(拡張性)
同じ関数を、異なる複数のオブジェクトで使い回すことができます。
function introduce() {
console.log(`私は${this.name}です。`);
}
const actor1 = { name: "佐藤", introduce: introduce };
const actor2 = { name: "鈴木", introduce: introduce };
actor1.introduce(); // 出力: 私は佐藤です。(thisはactor1)
actor2.introduce(); // 出力: 私は鈴木です。(thisはactor2)
関数は1つしか定義していませんが、thisが呼び出し元(持ち主)に応じて自動的に切り替わるため、コードの重複を減らすことができます。
【関連記事】
関数で使うthisは少し特殊
オブジェクトの「外」にある、通常の関数の中でthisを使う場合は注意が必要です。
function show() {
console.log(this);
}
show();
この場合、関数show( )を呼び出している明確な「持ち主(オブジェクト)」が前にいません。持ち主がいない状態で実行すると、JavaScriptのルールではグローバルオブジェクト(ブラウザ環境ならwindowオブジェクト、またはundefined)がthisに割り当てられます。
アロー関数ではthisの動きが違う
モダンJavaScriptの標準である「アロー関数( ( ) => { } )」を使う場合、thisの挙動はこれまで説明したものと180度変わります。これが実務で最も検索される重要トピックです。
普通の関数との違い
- 普通の関数(function):呼び出された時にthisが決まる(動的)。
- アロー関数( => ):関数が定義された場所のthisをそのまま固定して受け継ぐ(静的)。
アロー関数自身は、独自のthisを持ちません。
よくあるミス:undefined問題
オブジェクトのメソッドをアロー関数で書いてしまうことで、データが取得できなくなる現象(undefined問題)は、実務のコードレビューでも非常によく見かけます。
const client = {
name: "山田",
// メソッドをアロー関数で定義
greet: () => {
console.log(`こんにちは、${this.name}です。`);
}
};
client.greet(); // 出力: こんにちは、undefinedです。
なぜエラー(undefined)になるのか?
アロー関数は独自のthisを持たないため、clientオブジェクトのさらに外側(この場合はグローバル空間)のthisを参照してしまいます。その結果、グローバル空間にはnameというプロパティが存在しないため、undefinedが出力されてしまいます。
鉄則:
オブジェクトのメソッドを定義する際は、アロー関数ではなく、通常の関数記法(またはES6のメソッド短縮記法)を使用してください。
// 実務で推奨される綺麗な書き方(短縮記法)
const client = {
name: "山田",
greet() {
console.log(`こんにちは、${this.name}です。`); // 正しく「山田」を指す
}
};
【関連記事】
thisでよくある間違い(アンチパターン)
開発現場で見かける、thisにまつわる代表的な誤解を整理します。
- 「thisは常に定義されているオブジェクトを指す」という誤解
前述の通り、アロー関数を使った場合や、メソッドを変数に一度代入してから実行した場合など、呼び出し方によってはオブジェクトの外を指してしまいます。 - 「どこで使っても同じ意味になる」という誤解
同じファイル内であっても、トップレベル、オブジェクト内、ネストされた関数内、イベントリスナ内など、記述する「文脈(コンテキスト)」によってthisの正体は四変化します。
実務でthisはどこで使う?
モダン開発の現場において、具体的にthisがどのような機能で使われているかを紹介します。
クラス(Class)のコンストラクタとメソッド
JavaScriptでオブジェクト指向プログラミングを行う際、class構文の中でthisは主役になります。生成されるインスタンス(実体)のプロパティを保持するために必須です。
class Product {
constructor(name, price) {
this.name = name; // インスタンスにデータを保持
this.price = price;
}
display() {
console.log(`${this.name}: ${this.price}円`);
}
}
const item = new Product("マイク", 5000);
item.display(); // マイク: 5000円
DOMのイベント処理(Event Listener)
Webページ上のボタンがクリックされたときなどのイベント処理において、通常の関数を使うとthisは「イベントが発生したHTML要素そのもの」を指します。
const button = document.querySelector("#submit-btn");
button.addEventListener("click", function() {
// thisはクリックされた「button要素」を指す
this.classList.add("active");
});
【関連記事】
Reactなどのフレームワーク(補足)
レガシーなReact(クラスコンポーネント)では、状態(State)やメソッドへアクセスするためにthis.stateやthis.handleClick.bind(this)といった記述が大量に必要でした。
しかし、現在のモダンReact(関数コンポーネントとHooksが主流の時代)やVue.jsのComposition APIにおいては、thisを一切使わずにアプリケーションを構築できるよう設計されています。実務におけるthisの登場頻度は、数年前と比べて確実に減っています。
初心者はどこまで覚えればいい?
thisの仕様は奥が深く、call、apply、bindといったthisの中身を強制的に固定する高度なメソッドも存在します。しかし、実務レベルの初動において、それらを最初から完璧にマスターする必要はありません。
まずは以下の2点だけを確実に脳内にストックしてください。
- オブジェクトのメソッド内で使うthisは「そのオブジェクト自身」を指し、コードの再利用性を高めるために使う。
- アロー関数の中でthisを使うと、オブジェクトの外側を指していまいundefinedの原因になるため、メソッド定義には使わない。
この2つの原則さえ守れていれば、実務で発生する大半のthis関連のバグを回避できます。
まとめ:JavaScriptのthisを攻略する
一見すると複雑怪奇に見えるthisですが、その正体は「処理を実行している今の主役(オブジェクト)」です。
- thisは「今の持ち主」を表す動的なキーワード
- 呼び出し方(ドットの前にあるオブジェクト)によって中身が変わる
- アロー関数と組み合わせる時は挙動の違いに注意する
深い言語仕様に迷い込んで挫折するよりも、まずはご自身でシンプルなオブジェクトとメソッドを作り、コンソールでthisを出力して「今、誰を指しているのか」を観察することから始めてみてください。動的な挙動を体感することが、JavaScriptのデータフローを正確にコントロールするための確固たる第一歩となります。

