2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScriptのthisキーワードを理解する

Last updated at Posted at 2023-05-19

はじめに

JavaScriptの世界では、「this」というキーワードがよく出てきます。しかしこの「this」、一体何を指すのでしょうか。初学者にとってはこの「this」の挙動が分かりにくく、混乱を招くこともあります。この記事では、そんな「this」の基本的な振る舞いとその理由を解説します。

thisとは何か:コンテキストという視点

「コンテキスト(context)」とは、特定のコードが実行される際の状況や背景を指します。JavaScriptでは、「this」はそのコードがどのようなコンテキストで実行されているかによって、指す対象が変わります。

それでは、「this」がどのように動作するか、主なコンテキストとともに見ていきましょう

  1. グローバルコンテキスト(Global Context)

    ここでは、JavaScriptのコードが全体的な範囲、すなわち全体の実行環境であるグローバルコンテキストで動作しています。

    たとえば、ブラウザの場合、thiswindowオブジェクトを指します。これはブラウザの全体的な環境を表しています。

    console.log(this); // ブラウザでは "Window" と出力されます
    
  2. 関数コンテキスト(Function Context)

    関数内でのthisは、その関数がどのように呼び出されたかによって振る舞いが変わります。

    例えば、オブジェクトのメソッドとして関数が呼び出された場合、thisはそのメソッドを持つオブジェクトを指します。

    const myObject = {
      name: 'Alice',
      greet: function() {
        console.log('Hello, ' + this.name);
      }
    }
    
    myObject.greet(); // "Hello, Alice" と出力されます
    
  3. イベントコンテキスト(Event Context)
    イベント(例えば、ボタンのクリックなど)が発生した際のthisは、そのイベントを発火したHTML要素を指します。これは、ユーザーの操作に反応するJavaScriptコードを書く際に特に重要です。

    const myButton = document.querySelector('button');
    
    myButton.addEventListener('click', function() {
      console.log(this); // ここでの "this" はクリックされたボタン要素です
    });
    

クラス内でのthis

ES6以降のJavaScriptでは、クラス内で定義されたメソッド内でのthisはそのクラスのインスタンス(つまり具体的なオブジェクト)を指します。これはオブジェクトのメソッド内でのthisと同じ振る舞いですが、クラスを使うことでより堅牢なコード設計が可能になります。

class ExampleClass {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, ${this.name}`);
  }
}

const exampleInstance = new ExampleClass('Alice');
exampleInstance.greet(); // 'Hello, Alice'

コールバック関数とアロー関数

JavaScriptでは、関数を他の関数の引数として渡すことがよくあります。これをコールバック関数と呼びます。しかし、コールバック関数内でthisを使用すると、予想外の振る舞いをすることがあります。

const myObject = {
  name: 'Alice',
  waitAndGreet: function() {
    setTimeout(function() {
      console.log(`Hello, ${this.name}`);
    }, 1000);
  }
}

myObject.waitAndGreet(); // 'Hello, undefined'

ここでsetTimeoutのコールバック関数内のthisは、myObjectを指さずにグローバルオブジェクトを指してしまいます。これを解決する一つの方法としてアロー関数があります。アロー関数内のthisは、その関数が定義された時点でのthisを「覚えて」います。

const myObject = {
  name: 'Alice',
  waitAndGreet: function() {
    setTimeout(() => {
      console.log(`Hello, ${this.name}`);
    }, 1000);
  }
}

myObject.waitAndGreet(); // 'Hello, Alice'

このように、thisの挙動はその使用場所や関数の種類によって変わります。thisを使う際にはその点を意識し、必要に応じてアロー関数などを活用すると良いでしょう。

イベントハンドラ内でのthis

イベントハンドラ内での「this」は、そのイベントを処理するHTML要素を指します。これは、クリックイベントやマウスオーバーイベントなどのイベントハンドラ内で特に役立ちます。

const buttonElement = document.querySelector('button');

buttonElement.addEventListener('click', function() {
  console.log(this); // button element
});

コンストラクタとプロトタイプメソッド内でのthis

JavaScriptのコンストラクタやプロトタイプメソッド内での「this」は、そのメソッドを呼び出したインスタンス(具体的なオブジェクト)を指します。

function ExampleConstructor() {
  this.prop = 'Hello';
}

ExampleConstructor.prototype.method = function() {
  console.log(this.prop);
}

const exampleInstance = new ExampleConstructor();
exampleInstance.method(); // 'Hello'

call, apply, bindでのthis

JavaScriptには「call」、「apply」、「bind」というメソッドがあり、これらは関数やメソッドのthisを指定した値に変更することができます。

function greet() {
  console.log(this.name);
}

const person = { name: 'Alice' };

greet.call(person); // 'Alice'

ここではgreet関数のthispersonオブジェクトに変更し、その結果'Alice'が出力されました。

まとめ

JavaScriptのthisはその使用されるコンテキストによって指すものが変わるため、初めて学ぶ人にとっては少し難しい概念かもしれません。しかし、一つずつコンテキストを理解し、具体的なコード例を通じて学ぶことで、その振る舞いを掴むことができます。この記事が、this理解の一助となれば幸いです。

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?