Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
6
Help us understand the problem. What is going on with this article?
@clown0082

thisのみえぬぼくたち 〜コールバック関数内のthis〜

More than 3 years have passed since last update.

タイトルは某RPGの最終章をお借りしました。

こちらの記事が物凄〜くまとまっていて、正直これ読めばほぼ網羅しています。今回はタイトル通り、コールバック関数内におけるthisが指すものが何か、を備忘録としてまとめます。

本題の前にアロー関数

MDNでは以下のように書かれています。

アロー関数が登場するまでは、関数ごとに自身の this の値を定義していました(コンストラクタでは新しいオブジェクト、strict モード の関数呼び出しでは undefined、"オブジェクトのメソッド" として呼び出された関数ではそのときのオブジェクト、など)。これは、オブジェクト指向プログラミングをする上で煩わしいということが分かりました。

これがアロー関数ですと、thisを束縛しなくなりました。


const my_obj = {

   show: function() {
      console.log(this)   //=> Object {...}
   },

   show_arrow: () => {
      console.log(this)   //=> Window {...}
   }
}

はい。こっから本題です。

「タイマー」のコールバック関数

setTimeout, setIntervalのことです。タイマーはwindowオブジェクトに定義されているので、thisはwindowオブジェクトを指しますが、前述通りアロー関数はthisを束縛しないため、以下の例ではIncオブジェクトを指します。


function Inc() {
   this.num = 123

   setTimeout(function() {
      console.info(this)   //=> Window {...}
   })

   setTimeout(() => {
      console.info(this)   //=> Inc {...}
   })
}
const my_obj = new Inc()

「イベントハンドラ」のコールバック関数

今回は分かりやすくclickイベントにします。hogeというテキストをクリックするとconsoleに結果が出力されます。従来のfunctionではdivタグですが、アロー関数ではWindowオブジェクトになります。

<body>
  <div id="title">hoge</div>
</body>
const ttl = document.getElementById('title')


ttl.addEventListener('click', function() {
   console.info(this)
})
//=> <div id="title">hoge</div>


ttl.addEventListener('click', () => {
   console.info(this)
})
//=> Window {...}

※ちなみに、上記の結果はjQueryのコールバックでも同様の結果になります。

「forEach」のコールバック関数

以下のように、第二引数に何も指定しなければ、両方共Windowオブジェクトでした。


[1].forEach(function() {
   console.info(this)
})
//=> Window{...}


[1].forEach(() => {
   console.info(this)
})
//=> Window{...}

しかし、forEachの第二引数にオブジェクトを指定すると、従来のfunctionではthisが指定したオブジェクトになりますが、アロー関数ではWindowオブジェクトになりました。


const obj = {}

[1].forEach(function() {
   console.info(this)
}, obj)
//=> Object {}


[1].forEach(() => {
   console.info(this)
}, obj)
//=> Window{...}

※ また何か見つけたら随時更新予定

最後に

まだまだJavaScriptについては初心者ですので、マサカリは大歓迎です!(マサカリは本来悪い意味ではない、という論もありますが、そこは目をつむっていただけると幸いですw)

参考

6
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
clown0082
A Servant Leader of front-end team/an Executive/CEO(secondary) at Yumemi, Inc. We are the lions. CLI creator by nodejs, Riot.js(Collaborator), Challenge of an ordinary engineer.
yumemi
みんなが知ってるあのサービス、実はゆめみが作ってます。スマホアプリ/Webサービスの企画・UX/UI設計、開発運用。Swift, Kotlin, PHP, Vue.js, React.js, Node.js, AWS等エンジニア・クリエイターの会社です。Twitterで情報配信中https://twitter.com/yumemiinc

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
6
Help us understand the problem. What is going on with this article?