JavaScriptのthisとは

thisの登場

thisキーワードはJavaScriptの初期のバージョンであるECMAScript 1(1997年)から存在しています。JavaScriptの初期の設計者であるBrendan Eichが、thisを導入しました。

JavaScriptにおけるthisの動作や挙動は、他のプログラミング言語やオブジェクト指向の概念から影響を受けています。特に、JavaやC++などの言語の類似機能や、Smalltalkのメッセージパッシングなどの概念がthisの振る舞いに影響を与えました。

JavaScriptにおけるthisの使い方と挙動は、初期のバージョンから一貫していますが、厳密なモード(”strict mode”)が追加され、thisの扱いにいくつかの制約が追加されたECMAScript 5(2009年)以降、thisの取り扱いがより一貫性のあるものになりました。

thisキーワードとは

JavaScriptにおけるthisキーワードは、実行コンテキスト内で現在のオブジェクトまたは関数を参照するために使用されます。thisの値は実行時に決まりますが、その値は呼び出し元やコンテキストによって異なる場合があります。以下でthisの動作とその使用方法について詳しく説明します。

  1. オブジェクト内でのメソッド呼び出し: thisを使用することで、オブジェクト内のメソッドがそのオブジェクト自体を参照できます。これにより、メソッド内でオブジェクトのプロパティにアクセスしたり、他のメソッドを呼び出したりすることが容易になります。
const obj = {
  name: 'John',
  sayHello() {
    console.log(`Hello, ${this.name}!`);
  }
};

obj.sayHello(); // Hello, John!

  1. コンストラクタ内での新しいインスタンスの参照: thisを使用することで、コンストラクタ内で新しいインスタンスを参照できます。これにより、コンストラクタ内でインスタンス固有のプロパティを設定したり、インスタンス固有のメソッドを呼び出したりすることができます。
function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log(`Hello, ${this.name}!`);
};

const person1 = new Person('John');
person1.sayHello(); // Hello, John!

  1. イベントハンドラ内でのイベントの発生元の参照: イベントハンドラ内でthisを使用することで、イベントの発生元要素にアクセスできます。これは特に、DOMイベント処理でよく使用されます。
document.getElementById('myButton').addEventListener('click', function() {
  console.log(`Button ${this.id} clicked!`);
});

  1. 関数呼び出しの文脈の明確化: callapplyメソッドを使用することで、関数の呼び出し時にthisの値を明示的に指定できます。これは、関数を特定のオブジェクトのコンテキストで呼び出したい場合や、関数の呼び出し元の文脈を変更したい場合に役立ちます。
function greet() {
  console.log(`Hello, ${this.name}!`);
}

const person = { name: 'John' };

greet.call(person); // Hello, John!


これらはthisが解決する問題の一部です。thisは実行時のコンテキストに基づいて動作するため、柔軟性を持たせることができます。ただし、thisの挙動を正しく理解して使用することが重要です。

thisを使うべきではない場面

thisを使うべきではない場面もいくつかあります。以下にいくつかの例を示します。

  1. アロー関数の場合: アロー関数では、thisがレキシカルに固定されるため、関数が作成された時点での外部スコープのthisを参照します。そのため、アロー関数内でthisを使用しても、期待通りの動作をしない場合があります。アロー関数では、代わりに外部スコープの変数やthisを別の変数に割り当てることが推奨されます。
const obj = {
  name: 'John',
  sayHello: () => {
    console.log(`Hello, ${this.name}!`); // ここでのthisは期待通りに動作しない
  }
};

  1. コールバック関数内でのthis: コールバック関数(例:イベントハンドラ、非同期処理のコールバックなど)では、関数の呼び出し元や文脈によってthisの値が変わる場合があります。特に、コールバック関数が別のオブジェクトのメソッドとして呼び出される場合、thisは期待通りのオブジェクトを参照しないことがあります。このような場合は、アロー関数やbindメソッドを使用して明示的にthisを指定する必要があります。
const obj = {
  name: 'John',
  sayHello() {
    setTimeout(function() {
      console.log(`Hello, ${this.name}!`); // thisは期待通りに動作しない
    }, 1000);
  }
};

obj.sayHello();


これらの場面では、thisの代わりにクロージャや外部スコープの変数、または明示的なパラメータとして参照することが推奨されます。また、アロー関数やbindメソッドを使用してthisを明示的に指定することもあります。適切な文脈と使用方法を理解し、thisを使うべきではない場面を避けることが重要です。

bindメソッドを使用する場合:

bindメソッドは、関数に対して新しいthisの値を設定し、その新しい関数を返します。bindメソッドを使用してthisを指定したいオブジェクトにバインドします。

const obj = {
  name: 'John',
  sayHello: function() {
    setTimeout(function() {
      console.log(`Hello, ${this.name}!`);
    }.bind(this), 1000); // bindメソッドを使用してthisを明示的に指定する
  }
};

obj.sayHello();


bindメソッドの引数としてthisの値を指定することで、新しい関数が作成されます。その新しい関数は、bindメソッドに指定したthisの値を保持し、setTimeoutのコールバック関数として正しく機能します。

これらの方法を使用することで、アロー関数やbindメソッドを介して明示的にthisを指定できます。必要に応じて、適切な方法を選択してください。

以上がthisの説明になります。

お疲れ様です。