javascriptのthisについて

一言でいうと現在実行中の関数やメソッドが「何に対して」作用しているのかを示す変数のこと。
いくつかのパターンに分類して解説する。

グローバルコンテキストでのthis

グローバルスコープ(どのオブジェクトにも属さない場所)でthisを使うと、ブラウザ環境ではwindowオブジェクトを、Node.js環境ではglobalオブジェクトを指す。

console.log(this);  // ブラウザ: window, Node.js: global

通常の関数呼び出し

通常の関数呼び出しでは、thisはグローバルオブジェクト(ブラウザではwindow、Node.jsではglobal)を指す。

function myFunction() {
  console.log(this);
}
myFunction(); // ブラウザではwindow, Node.jsではglobal

オブジェクトメソッドとしての呼び出し

メソッドが所属するオブジェクトを指す。

const obj = {
  showThis: function() {
    console.log(this);
  }
};

obj.showThis();  // obj

コンストラクタ関数とthis

new演算子を使って関数をコンストラクタとして呼び出す場合、thisは新しく生成されるインスタンスを指す。
pythonにおけるselfにあたる。

function Person(name) {
  this.name = name;
}

const alice = new Person("Alice");
console.log(alice.name);  // "Alice"

アロー関数とthis

アロー関数内のthisは、アロー関数が定義されたスコープのthisの値を引継ぎ、それを関数内で使用する。
一般的な関数と違い、アロー関数は自身のthisを持たない。

const obj = {
  name: "Alice",
  showThis: function() {
    const arrowFunc = () => {
      console.log(this);
    };
    arrowFunc();  // obj
  }
};

obj.showThis();

callapplybindメソッドによる指定

callメソッドは、指定したthis値とともに関数を実行する。このメソッドの第一引数は関数内でthisとして参照されるオブジェクトで、それ以降の引数は関数へ渡される。

function greet(greeting, kutouten) {
  console.log(greeting + ', ' + this.name + kutouten);
}

const person = { name: 'Alice' };

greet.call(person, 'Hello', '!');  // 出力: "Hello, Alice!"

applyメソッドもcallと同様に、指定したthis値で関数を実行するが、applyは関数に渡す引数を配列として受け取る。

bindメソッドは強制的にオブジェクトと結びつける。

function greet(greeting, kutouten) {
  console.log(greeting + ', ' + this.name + kutouten);
}

const person = { name: 'Alice' };

const greetAlice = greet.bind(person);
greetAlice('Hello', '!');  // 出力: "Hello, Alice!"