thisキーワードの概要

thisキーワードとは

JavaScriptのthisは、オブジェクトを参照する特殊なキーワードです。thisが「どのオブジェクトを参照するか」はコードの書き方や実行場所(スコープやオブジェクトなど)によって変わるため、どのオブジェクトを参照しているか理解しにくい部分があります。

thisとスコープ

thisキーワードは、JSの何かしらのオブジェクトを参照していますが、大きく以下の環境で動作が異なります。

  • グローバルスコープ
  • 関数スコープ
  • アロー関数スコープ
  • クラススコープ

グローバルスコープ

ブラウザ上などのグローバル環境下で this を利用すると Windowオブジェクトを指します。

// ブラウザの場合、windowオブジェクトが出力
console.log(this)

関数スコープ

HTMLのイベントに第1引数に this、第2引数に event の関数を設定した場合です。

<a onclick="method(this, event)">Click</a>

関数内の this

JSの関数内の this はグローバルオブジェクト(Windowオブジェクト)ととして利用できます。

function method(element, event) {
    // Windowオブジェクト
    console.log(this)
}

関数型オブジェクトスコープ

関数型オブジェクト内の this は、関数の親のスコープを引き継ぎます。

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.greet = function () {
        return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
    };
}
  • 関数型オブジェクトはユーザ定義オブジェクトで解説します。

クラス型オブジェクトのスコープ

クラス型オブジェクト内の this は、インスタンスのプロパティに利用します。

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greet() {
        return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
    }
}
  • クラス型オブジェクト詳しくはユーザ定義オブジェクトで解説します。

thisとスコープ

ファイル構成

basic/
├── js/
│      └── this.js
└── this.html
this.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザ定義オブジェクト</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="bg-gray-100 flex justify-center">
    <main class="bg-white shadow-md rounded-lg p-6 w-full max-w-2xl mx-auto">
        <h1 class="font-bold text-2xl text-center mb-6">thisオブジェクト</h1>
        <div class="p-6">
            <h3 class="font-bold text-md py-3">this.location.href</h3>
            <div id="window-href" class="p-4 bg-gray-50 rounded-md shadow-sm"></div>

            <h3 class="font-bold text-md py-3">this.navigator.userAgent</h3>
            <div id="window-userAgent" class="p-4 bg-gray-50 rounded-md shadow-sm"></div>

            <h3 class="font-bold text-md py-3">this.screen.width</h3>
            <div id="window-size" class="p-4 bg-gray-50 rounded-md shadow-sm"></div>

            <h3 class="font-bold text-md py-3">clickEvent(this, event) で、className を表示</h3>
            <div id="this-object" class="p-4 bg-gray-50 rounded-md shadow-sm"></div>

            <h3 class="font-bold text-md py-3">イベントタイプ</h3>
            <div id="event-object" class="p-4 bg-gray-50 rounded-md shadow-sm"></div>

            <button onclick="clickEvent(this, event)" class="p-2 border border-gray-500 rounded-md">Click</button>
        </div>        
    </main>
    <!-- 外部JavaScriptファイルの読み込み -->
    <script src="js/this.js" defer></script>
</body>

</html>
js/this.js
function clickEvent(element, event) {

}

グローバルスコープ

js/this.js
// thisオブジェクト(グローバル)
console.log(this)

Windowオブジェクト

コンソールで確認すると、グローバルスコープのthisWindowオブジェクトだとわかります。

コンソール
Window {window: Window, self: Window, document: document, name: '', location: Location, …}

Windowオブジェクトのプロパティ

Windowオブジェクトには色々なプロパティやメソッドがビルトインされています。「現在のURL」「ユーザエージェント」「ウィンドウサイズ」をブラウザ表示して確認します。

js/this.js
// 現在のURL
document.getElementById('window-href').innerText = this.location.href;
// ユーザエージェント
document.getElementById('window-userAgent').innerText = this.navigator.userAgent;
// ウィンドウサイズ
document.getElementById('window-size').innerText = `${this.screen.width} x ${this.screen.height}`;

ブラウザを更新して this(Windowオブジェクト)のプロパティを確認します。

ブラウザ

関数スコープ

クリックイベントの関数 clickEvent() を設定しました。第1引数は this 、第2引数は event とします。

<button onclick="clickEvent(this, event)" class="p-2 border border-gray-500 rounded-md">Click</button>

関数内の this

関数 clickEvent()this は、Windowオブジェクトとして処理されます。

js/this.js
// 引数 element は、HTMLイベントで設定した this
function clickEvent(element, event) {
    // Windowオブジェクト
    console.log(this)
}

第1引数の this

関数の第1引数 this は、関数内では Elementオブジェクト として処理されます。

js/this.js
// 引数 element は、HTMLイベントで設定した this
function clickEvent(element, event) {
    // Element取得
    console.log(element);
    // Elementからクラス名表示
    document.getElementById('this-object').innerText = element.className;
}

コンソールに Windowオブジェクトが表示されました。

コンソール
Window {window: Window, self: Window, document: document, name: '', location: Location, …}

ブラウザにbuttonタグの class プロパティの設定値が表示されました。

ブラウザ

第2引数の event

関数の第2引数 event は、関数内では Eventオブジェクト として処理されます。

js/this.js
// 引数 element は、HTMLイベントで設定した this
function clickEvent(element, event) {
    // イベント取得
    console.log(event);
    // イベントのタイプを表示
    document.getElementById('event-object').innerText = event.type;
}

コンソールに Eventオブジェクトが表示されました。

コンソール
PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}

ブラウザにbuttonタグのイベントタイプが表示されました。

ブラウザ