🏹

【JS】通常の関数とアロー関数のthisの違い

2024/05/22に公開

調べたきっかけ

javascriptの問題を解いていた時に、アロー関数で簡潔に書こう!と思って書いてみたら思った通りに動かなかったので、原因を調べてみたら通常の関数とアロー関数のthisの違いが原因でした。勉強したことはあったけど実際に困ったことがなかったので知識が定着していませんでした、、この機会に備忘録としてまとめたいと思います

通常の関数でのthis

通常の関数では、thisは関数がどのオブジェクトのメソッドとして呼び出されたかによって、thisが指すものが変わります。(呼び出される環境のことをコンテキストという!)
例)

  <ul class="list">
    <li class="apple">リンゴ</li>
    <li class="orange">みかん</li>
    <li class="grape">ぶどう</li>
  </ul>
document.addEventListener('DOMContentLoaded',function(){
  const LIitems = document.querySelectorAll('li');
  LIitems.forEach(function(item){
// functionを使って記述
    item.addEventListener('click',function(){
      alert(this.className);
    })
  })
})

この場合は、this.classNameのthisは、クリックされた要素を指します。
そのため、このプログラムを実行すると、クリックした要素のclass名がアラートで出力されます!

アロー関数でのthis

アロー関数ではthisは定義されたスコープを継承します。アロー関数内のthisは、アロー関数が定義された場所のthisをそのまま使います。
通常の関数での例をアロー関数に置き換えてみます。
例)

  <ul class="list">
    <li class="apple">リンゴ</li>
    <li class="orange">みかん</li>
    <li class="grape">ぶどう</li>
  </ul>
document.addEventListener('DOMContentLoaded',function(){
  const LIitems = document.querySelectorAll('li');
  LIitems.forEach(function(item){
// アロー関数を使って記述
    item.addEventListener('click',()=> {
      alert(this.className);
    })
  })
})

アロー関数内のthisは、アロー関数が定義されたスコープ、DOMContentLoadedイベントリスナーのコールバック関数のスコープを継承します。DOMContentLoadedイベントリスナーはブラウザではwindowオブジェクトで実行されるため、アロー関数内のthisはwindowオブジェクトを指します。そのため、window.classNameを参照しようとしますが未定義なので、アラートではundefinedが出力されます!

まとめ

通常の関数でのthisとアロー関数でのthisは参照先が違います。そのため、なんでもアロー関数で書いてしまうと思った通りに動かなくなってしまうので違いを意識して実装することが必要です!

Discussion