Movatterモバイル変換


[0]ホーム

URL:


LoginSignup
36

Go to list of users who liked

40

Share on X(Twitter)

Share on Facebook

Add to Hatena Bookmark

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptのthisもこれで完璧!呼び出し方で変わる5つのパターン

Last updated atPosted at 2024-11-09

こんにちは、とまだです。

JavaScript アドベントカレンダー 2024 のうち、2 日目の記事をお届けします!

私が本格的に現場で JavaScript をはじめたとき、「this を理解したら中級者」と言われました。

それぐらい、this は JavaScript において重要な概念です。

突然ですが、以下のコードの出力結果は分かりますか?

constuser={name:'Alice',greet(){console.log(`こんにちは、${this.name}さん!`);},};constgreet=user.greet;greet();// ???

どうでしょうか?
全体として、流れとしてはuser.greet を呼び出しているので、以下のように出力されると思われるかもしれません。

こんにちは、Aliceさん!

しかし、実際の出力結果は以下の通りです。

こんにちは、undefinedさん!

この結果に驚いた方も多いのではないでしょうか?

実はthis は、どう呼び出すかによって値が変わる曲者なんです。

今回は「JavaScript の this を完全に理解する」ことを目指して、5 つのパターンを解説します!

なぜ this を理解する必要があるの?

JavaScript 経験者なら、このような経験があるかもしれません。

  • コードは間違ってないはずなのにundefined が出る
  • React でthis.setState が動かない
  • イベントハンドラの中でthisundefined になる

これらの問題は、全てthis の理解が足りないことが多いです。

「this がよく分からない」と感じている方は、ぜひこの記事を読み進めてください!

this の基本:「誰が呼び出したか」が重要

まず、this は「関数を呼び出したもの」を指すと覚えておきましょう。

例えば、以下のようなコードを見てみましょう。

constuser={name:'Alice',greet(){console.log(`こんにちは、${this.name}さん!`);},};// userがgreetを呼び出すuser.greet();// こんにちは、Aliceさん!// グローバルスコープでgreetを呼び出すconstgreet=user.greet;greet();// こんにちは、undefinedさん!

同じ関数なのに、呼び出し方によって結果が変わってしまいます。

なぜこうなるのか、5 つのパターンを見ながら理解していきましょう。

this の 5 つの顔

1. メソッド呼び出し:オブジェクトのメソッドとして呼ぶ場合

オブジェクトのメソッドとして呼び出す場合、this はそのオブジェクトを指します。

constuser={name:'Alice',greet(){console.log(`こんにちは、${this.name}さん!`);},};user.greet();// こんにちは、Aliceさん!

この場合、関数を呼び出したのはuser オブジェクトなので、thisuser を指します。

2. 普通の関数呼び出し:単独で呼び出す場合

普通の関数として呼び出す場合、thisundefined(strict モード)またはwindow(非 strict モード)を指します。

functionstandalone(){console.log(this);}standalone();// undefined または window

これは意図しない動作の原因になりやすいので、気をつけましょう。

3. アロー関数:外側の this をそのまま使う

アロー関数のthis は、関数が定義された場所のthis を引き継ぎます。

もう少し正確に言うと、アロー関数はthis を持たず、外側のthis をそのまま使います。

constuser={name:'Alice',// 通常の関数greet(){constarrow=()=>{console.log(`こんにちは、${this.name}さん!`);};arrow();},};user.greet();// こんにちは、Aliceさん!

アロー関数はthis を持たず、外側のthis をそのまま使うので、コールバック関数でよく使われます。

4. new による呼び出し:新しいオブジェクトを指す

new で関数を呼び出すと、this は新しく作られたオブジェクトを指します。

functionUser(name){this.name=name;}constalice=newUser('Alice');console.log(alice.name);// Alice

これは、JavaScript のクラス構文の内部でも使われています。

5. bind/call/apply による呼び出し:this を固定する

bindcallapply メソッドを使うと、this の値を明示的に指定できます。

constuser={name:'Alice',greet(){console.log(`こんにちは、${this.name}さん!`);},};constgreet=user.greet.bind(user);greet();// こんにちは、Aliceさん!

この方法は、イベントハンドラなどでthis の値を固定したい場合によく使われます。

実践的な使い方:よくあるバグと解決策

イベントハンドラでの問題

最もよく遭遇するthis のバグは、イベントハンドラでの問題です。

constbutton=document.querySelector('button');constuser={name:'Alice',handleClick(){console.log(`${this.name}がクリックしました!`);},};// 🙅‍♂️ ダメな例:thisがundefinedになるbutton.addEventListener('click',user.handleClick);// 🙆‍♂️ 良い例1:bindを使うbutton.addEventListener('click',user.handleClick.bind(user));// 🙆‍♂️ 良い例2:アロー関数でラップするbutton.addEventListener('click',()=>user.handleClick());

イベントハンドラ内でthis を使いたい場合は、bind やアロー関数を使ってthis の値を固定しましょう。

React での this の問題

React でクラスコンポーネントを使う場合も、this の問題に遭遇することがあります。

classButtonextendsReact.Component{// 🙅‍♂️ ダメな例:thisがundefinedになるhandleClick(){this.setState({clicked:true});}// 🙆‍♂️ 良い例1:メソッドをアロー関数で定義handleClick=()=>{this.setState({clicked:true});};render(){// 🙆‍♂️ 良い例2:bindを使うreturn<buttononClick={this.handleClick.bind(this)}>Clickme!</button>;}}

ここでも、bind やアロー関数を使ってthis の値を固定することで問題を解決できます。

最近の React では関数コンポーネントと Hooks を使うことが推奨されており、その場合は this の問題を気にする必要はありません。

まとめ

今回説明した内容を整理すると、以下のようになります。

  1. this は「関数を呼び出したもの」を指す
  2. 呼び出し方によってthis の値が変わる
  3. 5 つのパターンを覚えておく
    • メソッド呼び出し
    • 普通の関数呼び出し
    • アロー関数
    • new による呼び出し
    • bind/call/apply による呼び出し

覚えるのが大変そうに見えますが、基本的な考え方さえ理解できれば、あとは実践の中で自然と身についていきます。

最後まで読んでいただき、ありがとうございました!

他にもアドベントカレンダー記事を書いています!

他にも、2024 年のアドベントカレンダーに参加しています。

以下の記事でまとめているので、よければ他の記事も読んでいただけると嬉しいです!

36

Go to list of users who liked

40
1

Go to list of comments

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36

Go to list of users who liked

40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?


[8]ページ先頭

©2009-2025 Movatter.jp