JavaScriptの改修でコードの中でこんなの見かけて「???」ってなりました。

let _this = this;

いや、なんで自分を変数に?_thisってなに?って思ったのがきっかけで調べたら、これは JavaScript の 「this」迷子問題に関係してる古いけど重要なテクニックだったんです。

thisが関数の呼び出し方によって値が変わるため(特にコールバック関数ではイベントが発生した要素)クラスのインスタンスの参照を保持できません

💡 そこで

let _this = this; は、ES5時代の this の扱いを補うための回避テクニックです。
現代(ES6以降)ではアロー関数 (=>) を使えば、もっとスマートに解決できます!

🕰️ なぜ _this を使ってたの?

ES5(2009年ごろ)までは、関数の中で this の参照が簡単に変わってしまうのが普通でした。
特に jQuery でイベントを使うとき、よくハマってました…(体験談)

this が変わっちゃう問題

class Example {
  constructor() {
    this.name = "MountEngineer";
  }

  hello() {
    let _this = this;

    $(".btn").on("click", function () {
      console.log(_this.name); // → "MountEngineer"
      console.log(this.name);  // → undefined
    });
  }
}

この function() の中の this は、Exampleインスタンスじゃなくてクリックされたボタン要素を指します。

なので、元の this(=Exampleのインスタンス)を _this に保存しておいて、
function の中で使えるようにする、っていう涙ぐましい努力が必要だったわけです…。


🤖 今はこう書く!アロー関数で解決✨

ES6(2015年)以降なら、=>(アロー関数)を使ってこの問題をシンプルに解決できます!

class Example {
  constructor() {
    this.name = "MountEngineer";
  }

  hello() {
    $(".btn").on("click", () => {
      console.log(this.name); // → "MountEngineer"
    });
  }
}

アロー関数は「自分の this を持たない」ので、外側の this をそのまま使えるんです。これがめちゃくちゃ便利!

アロー関数と通常関数の比較表

項目通常の関数アロー関数
構文function() { ... }() => { ... }
thisの参照呼び出し時に決定(動的)定義時のスコープから継承(静的)
使用例function() { _this.method(); }() => { this.method(); }
変数保存let _this = this; が必要不要
メリット柔軟なコンテキスト変更が可能コードが簡潔に書ける
this参照エラーが起きにくい
適した場面メソッドとして定義する場合<br>thisを動的に変えたい場合コールバック関数<br>イベントハンドラ<br>setTimeout内の関数

🧠 専門用語ざっくり解説

用語説明
this関数の実行コンテキスト(状況)によって意味が変わる魔物。
スコープ変数や関数が使える「範囲」のこと。
クロージャ外側の関数の変数を、内側の関数が覚えてる状態。
アロー関数ES6で登場。外の this をそのまま使える新しい書き方。
レキシカル thisアロー関数が採用してる、this の決まり方。

🧓 let _this = this; は今でも使う?

基本は「使わない」でOK!でも、以下のような場面ではまだ出会うかも。

  • 古いテーマやプラグインのメンテ中(←今回みたいなケース!)
  • ES6が使えないレガシー環境
  • jQuery ベッタリのコード
  • Babelなどトランスパイル環境を使ってない開発

でも 新しく書くコードではアロー関数を使おう! が現代のスタンダードです。