導入
JavaScriptにおいて、オブジェクトは単なるデータの入れ物ではなく、振る舞い(メソッド)を持つことができます。この「データと振る舞いを一つの単位として扱う」概念は、オブジェクト指向プログラミングの基礎です。しかし、メソッド内で自身のデータにアクセスするためのキーワード「this」は、他のプログラミング言語とは異なる独特の挙動をします。この仕組みを正しく理解することは、バグを減らし、クリーンなコードを書くために不可欠です。
基礎知識
オブジェクトのプロパティとして定義された関数を「メソッド」と呼びます。
メソッド内で自身のオブジェクトのプロパティを参照したい場合、変数名(例:user.name)を直接使うのは避けるべきです。なぜなら、変数名が変わったり、オブジェクトが別の変数に代入されたりすると、参照が壊れる可能性があるからです。
そこで登場するのが this です。this は「呼び出し元」のコンテキストを参照します。基本的に、「ドットの左側にあるオブジェクト」が this になります。
実装/解決策
this を使う際は、関数が「どこで宣言されたか」ではなく「どう呼び出されたか」が重要です。
・obj.method() として呼び出された場合、this は obj を指します。
・単体で関数として呼び出された場合、this は undefined(strictモード)またはグローバルオブジェクトを指します。
また、アロー関数は特殊です。アロー関数には独自の this が存在せず、外側のスコープの this をそのまま引き継ぎます。この特性は、コールバック関数内などで this を固定したい場合に非常に便利です。
サンプルプログラム
以下は、計算機オブジェクトを作成し、this を活用して状態を操作する例です。
const calculator = {
a: 0,
b: 0,
// ユーザーから値を取得するメソッド
read() {
this.a = Number(prompt('1つ目の値を入力してください', 0));
this.b = Number(prompt('2つ目の値を入力してください', 0));
},
// 合計を計算するメソッド
sum() {
return this.a + this.b;
},
// 積を計算するメソッド
mul() {
return this.a this.b;
}
};
// 呼び出し例
calculator.read(); // ここではドットの左側の calculator が this になる
alert("合計: " + calculator.sum());
alert("積: " + calculator.mul());
応用・注意点
1. メソッドチェーンの活用:
メソッド内で return this; を記述すると、自身のオブジェクトを返すことができます。これにより、複数のメソッドを obj.up().up().down() のように繋げて呼び出すことが可能になり、コードの可読性が向上します。
2. “this” の消失に注意:
メソッドを別の変数に代入して呼び出すと、呼び出し時のドットがなくなるため this が失われます。
例:const func = user.sayHi; func();
この場合、this が正しく参照されずエラーや意図しない動作の原因となります。このような場面では、アロー関数を使ってスコープを固定するか、`.bind()` を使用するなどの工夫が必要です。
3. アロー関数の使い分け:
「自身の this が欲しい場合(通常のメソッド)」は関数式を、「外側の this を保持したい場合(イベントハンドラやタイマー内のコールバック)」はアロー関数を、という使い分けを意識しましょう。