💡

JavaScriptでthisはどんな時に使うのか

2024/08/11に公開

thisってなに?

以下のように説明されています。
this の値はどのように関数が呼ばれたかによって決定されます (実行時結合)。
これは実行時に代入によって設定することはできず、関数が呼び出されるたびに異なる可能性があります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/this

関数が呼び出されるたびに変わるとは

例えば以下のように比較した場合aを別のオブジェクトに追加すると参照先のオブジェクトが変わります。

var a = function() {
  return this;
};
const obj = {
  method: a
};


var b = function() {
  return this;
};

a() // `this` はglobal objectを参照
obj.method() // `this` をobjを参照
console.log(a() === b()); // true
console.log(obj.method() === b()) // false

thisの基本的な使い方

thisは、参照先の指定がない場合は、グローバルオブジェクトになります。
参照先がある場合はそのオブジェクトを参照する。

1.関数内やメソッド内で使う

メソッド内で利用

const person = {
  name: "Alice",
  greet: function() {
    console.log("Hello, " + this.name); // `this` はpersonオブジェクトを参照
  }
};

person.greet(); // "Hello, Alice" と表示される

関数内で利用

function showThis() {
  console.log(this);
}

const obj = {
  method: showThis
};

obj.method(); // `this` はobjを参照
showThis();   // `this` はグローバルオブジェクト(またはstrictモードではundefined)を参照

2.コンストラクタ関数で使う

class Person {
  constructor(initName) {
     this.name = initName; // `this` は新しく作成されるオブジェクトを参照
  }

  greeting() {
    console.log('Hello! My name is ${this.name}')
  }
}

const person1 = new Person("Bob");
person1.greeting(); // "Hello! My name is Bob"

参照先を指定したい場合

以下のように参照先が不明になったthisに参照先を設定する方法を紹介する

function Timer() {
  this.seconds = 0; 
  console.log(this.seconds); // Timerオブジェクトのthis
  setInterval(function() {
    this.seconds++; // この `this`  は Timer オブジェクトを指していない
    console.log(this.seconds);
  }, 1000);
}

const myTimer = new Timer(); // `this` はグローバルオブジェクトを参照している

アロー関数を使う

アロー関数内でthisを使うと外側のオブジェクトを参照する。

function Timer() {
  this.seconds = 0; // `this` は Timerオブジェクト
  
  setInterval(() => {
    this.seconds++; // アロー関数の `this` は Timer オブジェクトを指す
    console.log(this.seconds);
  }, 1000);
}

const myTimer = new Timer();

this を別の変数に保存して使う

忘れてしまうと参照がされなくなるので注意が必要

function Timer() {
  this.seconds = 0; 
  console.log(this.seconds); // Timerオブジェクトのthis
  self = this;
  setInterval(function() {
    self.seconds++; // この this は Timer オブジェクトを指す
    console.log(self.seconds);
  }, 1000);
}

const myTimer = new Timer();

bindメソッドを使う

function Timer() {
  this.seconds = 0;
  
  setInterval(function() {
    this.seconds++; // この `this` は bind によって Timer オブジェクトを指す
    console.log(this.seconds);
  }.bind(this), 1000); // ここで `this` を Timer オブジェクトにバインドする
}

const myTimer = new Timer();

Discussion