JavaScript

【JavaScript】アロー関数のthisの挙動を実例から学ぶ【JQueryサンプル】

【JavaScript】アロー関数のthisの 挙動を実例から学ぶ【JQueryサンプル】

今回は「アロー関数」(Arrow functions) と「this」のお話です。

次にような方にとっては勉強・復習になるかと思います。

アロー関数知ってるけど、普通の関数とどう違うの?

アロー関数を使うときに気をつけるべき点ってある?

アロー関数が用意される前までは「function」キーワードを使って関数を定義する選択肢しかありませんでした。

既に関数キーワードがあるのになぜ、アロー関数が用意されたのでしょうか?

アロー関数が生まれた理由も含めて、今回の記事では次の内容について話していきます。

今回の記事内容
  • アロー関数が生まれた理由
  • 実例からみるthisの挙動

それでは、1つ目の「アロー関数が生まれた理由」から解説します。

アロー関数が生まれた理由

既に「function」キーワードが存在しているのにも関わらず、なぜアロー関数が用意されたのでしょうか?

それは大きく次の2点の理由からです。

アロー関数ができた理由
  1. 関数を短く書きたい
  2. this を束縛したくない

関数を短く書きたい

1つ目の理由はそのまんまですね。実際に文字数がどれくらい短くなったか比べてみましょう。

文字数の比較

関数の種類 文法 文字数
通常の関数 function(){} 12文字
アロー関数 ()=>{} 6文字

上記の表からわかるように、アロー関数を使うことで文字数が従来の書き方と比べて半分に減りました。

たったの6文字と感じるかもしれませんが、実際には開発中に関数の定義をする場面は何度もあります。地味ではありますが、タイピング数が少なくなるのは嬉しいことです。

this を束縛したくない

1つ目の理由も嬉しいことですが、アロー関数が一番力を発揮するのは「this」の取り扱い方です。

JavaScriptの「this」の挙動はクセが強くて、必ず初心者がつまづくポイントでもあります。

JavaScriptの「this」の挙動は言葉だけで理解するのは難しいので実際にサンプルコードを使って説明します。

なお「this」の挙動をわかりやすくするために「class」を使って説明しています。

classについて、あまり理解していない方は「JavaScriptでクラスを作ろう! class構文の使い方徹底解説」が参考になるかと思います。

それでは早速コードを見ていきましょう。

通常の関数を使った場合

実行結果は次のとおりです。

通常の関数を使ったときのthisの挙動通常の関数を使ったときのthisの挙動

 

実行結果の画面右側がコンソールの出力、左側がHTMLの表示部分になります。

左側のHTML表示部分の数字の「0」が「NaN」という文字に置き換わっているのがわかるかと思います。

JavaScriptのコード上にもコメントに書いていますが、NaNと表示されるまでの流れは次のとおりです。

NaNに置き換わるまで
  1. ボタンがクリックされた時に呼ばれるコールバック関数のthisを11, 12行目で確認するとthisはボタン(= button)自身を指している
  2. 20行目の「this.count」は「button.count」という意味になる
  3. this.count(= button.count)は定義されていないので「undefined」となる
  4. undefinedのインクリメント(undefined++)はNaNとなる
  5. 20行目でthis.count(= button.count)にはNaNがセットされる
  6. 21行目でtargetElementのinnerHTML(HTML表示部分)にthis.count(= NaN)がセットされる
  7. HTMLの「0」と表示されていたところが「NaN」に置き換わる

アロー関数を使った場合

それでは次にアロー関数をつかった場合を見ていきましょう。

HTMLは同じものを使うのでJavaScriptのサンプルコードだけ書いていきます。

実行結果は次のとおりです。

アロー関数を使ったときのthisの挙動アロー関数を使ったときのthisの挙動

 

通常の関数(= functionキーワード)を使ったときと挙動が変わって、正しく数字がインクリメントされているのがわかります。

上の実行結果画像の右半分を確認してみると、「thisの内容 : Counter {count : 0}」のように出力されているのがわかるかと思います。

これは、「this」がCounterインスタンスであることを表しています。

インスタンスとはクラスを使ったときの概念で、ここではオブジェクトと同じ意味だと認識していただいて大丈夫です。

例: 「const counter = {counter : 0}」・・・counterオブジェクト

通常関数を使ったときと、アロー関数を使ったときの「this」の内容について改めてまとめてみましょう。

buttonをクリックしたときのthisの内容

関数の種類 thisの内容
通常の関数 buttonのDOM
アロー関数  Counterインスタンス

上記の表から「通常の関数」を使ったときは、クリックしたときのHTMLの要素(今回の場合だとbutton)がthisになることがわかります。

「アロー関数」を使った場合はクリックしたHTMLの要素にならず、処理が実装されているオブジェクト(今回の場合はCounterインスタンス)がthisになることがわかります。

処理が実装されているオブジェクト」と言葉で説明するだけでは難しいと思うので、その他のコールバック関数の使用例を見て理解していきましょう。

実例からみるthisの挙動

実例ではJQueryを使っていきます。

今回はDOMの読み込みが完了したときに呼ばれる「$(function() {})」を省略しないで「$(document).ready(function(){})」を使って説明します。

明示的に「document」を使っているというのを理解することで、「this」の内容が「document」になるのか、それ以外のものになるのかわかりやすくなります。

それでは次のサンプルコードを見ていきましょう。

実行結果は次のとおりです。

JQueryを使って読み込み完了したときのthisの内容JQueryを使って読み込み完了したときのthisの内容

 

実行結果の画像の出力内容を見ると、通常の関数を使ったときとアロー関数を使ったときの「this」の内容は次のとおりです。

DOM読み込み完了時のthisの内容

関数の種類 thisの内容
通常の関数 documentオブジェクト
アロー関数 Windowオブジェクト

1つ前の章の「this を束縛したくない」で説明したボタンクリック時のそれぞれの関数を使ったときの「this」の内容と比較してみましょう。

buttonをクリックしたときのthisの内容

関数の種類 thisの内容
通常の関数 buttonのDOM
アロー関数 Counterインスタンス

通常の関数の場合は、クリックやDOM読み込み完了時などのイベントが実行されるとき、「this」の内容はイベントの本体になります。

イベントの本体とは今回の場合だと次のようになります。

イベントの本体
  • ボタンクリック時 => ボタンがイベントの本体
  • DOM読み込み完了時 => documentがイベントの本体

「イベント」についてよくわからない方は、次の記事で詳しく解説しているのでそちらを参考にしていただけたらと思います。

アロー関数を使った場合、「this」の内容は「処理が実装されているオブジェクト(場所)がthis」と説明しました。

その上で、ボタンクリック時とDOM読み込み完了時の処理が実装されているオブジェクト(場所)をまとめると次のようになります。

処理が実装されている場所
  • ボタンクリック時 => Counterクラスのメソッド内(= Counterインスタンス)
  • DOM読み込み完了時 => グローバル空間(= Windowオブジェクト)

関数内やオブジェクト内ではなく、ファイル直下にコードを記述した場合、JavaScriptだとそのコードはグローバルオブジェクト(= グローバルスコープ)に所属することになります。

ブラウザのグローバルオブジェクトは「windowオブジェクト」となるため、画像内のアロー関数の出力結果の内容を見ると「Window」となっていることがわかります。

「グローバルオブジェクト」については以下の記事が参考になるかと思います。

まとめ

JavaScriptのthisはクセが強くて初心者にとって理解するハードルが高い部分でもあります。

通常の関数を使ったときと、アロー関数を使ったときで「this」の挙動が変わるということをここまでサンプルコードを交えて説明してきました。

もう一度ここで通常関数とアロー関数を使ったときの「this」の違いを確認してみましょう。

関数の種類 thisの内容
通常の関数 イベントの本体
  • ボタンをクリックしたときのボタンそのもの
  • DOM読み込み完了時のdocumentそのもの
アロー関数 処理の実装場所
  • Counterクラスのメソッド内でクリック時の処理が実装されている場合は、Counterインスタンスがthisとなる
  • グローバルスコープでDOMの読み込み完了時の処理を実装している場合は、Windowオブジェクトがthisとなる

JavaScriptの「this」を理解して、使いこなせるようにことは脱初心者の1つのステップにもなるので、今回の記事が「this」を理解するきっかけになったら嬉しいです^^

もし「もう少し詳しく教えて欲しい」などありましたら、以下よりご連絡をいただけたらと思います^^

 

【3つの特典付き】Webエンジニアに必要な基礎スキルを体系的に効率良く身につけたいですか?

LINE登録で無料特典を受け取る

次のような方向けに、学習をサポートするコンテンツを無料プレゼントしています。

  • Webエンジニアになりたいけど何から学習を始めれば良いかわからない
  • 今まで独学で頑張ってきたけど、独学に限界を感じてきた
  • プログラミングは出来るけど、大きめのコードが書けない

「プレゼント詳細が知りたい」「プレゼントを受け取りたい」といった方は、以下のボタンをクリックして詳細ページをご確認ください。

無料特典を受け取る

 

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です