LoginSignup
3
2

More than 3 years have passed since last update.

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

Posted at

最近JavaScriptを勉強し始めた中でthisの使い方がイマイチぴんと来ていないので、今回は、

  • function(){・・・}(通常関数)
  • ()=>{・・・}(アロー関数)

thisの使い方の違いについてまとめます。

何が違うのか?

私自身、調べる前は「thisの範囲が違うらしい」ということくらいしか分かっていませんでした。

違いを一言で言うと、

  • 通常関数のthisは、function を呼んだ時の . の前についているオブジェクト
  • アロー関数のthisは、関数の外のthis

を指してます。

通常関数を先に説明をします。

通常関数のthis

function test() {
    console.log(this)
}
var obj = {}
obj.test = test
obj.test() // => {test: ƒ}

thisfunctionを呼んだ時の.の前についているobjオブジェクトとなります。

function test() {
    console.log(this)
}
test() // => Window {frames: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}

オブジェクトを指定しない場合は、グローバルオブジェクトになります (non-strict モード時)。 strict モードでは undefined になります。

とまあ、通常関数の場合は関数の呼び出し方に応じてthisの中身が変わります。下の記事に呼び出し方による違いが書いてあります。

JavaScript の this を理解する多分一番分かりやすい説明 - Qiita

記事は非常に分かりやすく書いてあります。が、実行の仕方によってthisが変わってしまい、分かりにくくないですか? 私は読んでいて嫌になってきました。

その複雑さを改善したのがアロー関数のようです。

アロー関数のthis

アロー関数のthisは、関数の外側のthisに固定されます。

const test = () => {
    return this
}
// 関数の外側のthis
const lexicalThis = this

// 関数定義したタイミングで、関数の外側のthisを参照する
console.log(test() === lexicalThis) //=> true

// メソッドとして実行しても、thisはメソッドが属するオブジェクトを指さない
const obj = { method: test }
console.log(obj.method() === obj) //=> false
console.log(obj.method() === lexicalThis) //=> true

先ほどの通常関数のobj.test()this=objとして扱っていたのに対して、アロー関数のobj.test()this=lexicalThis(関数の外側のthis)として扱っていることが分かります。
アロー関数のthisは、.前のオブジェクトは指さず、必ず関数の外側のthisを指します。

また、強制的にあるオブジェクトと結びつけるbind等も無視するようです。通常関数では有効です。

通常関数のbindの例
function test() {
    console.log(this)
}
var obj = { name: "obj" }
var check = test.bind(obj)
check() // => {name: "obj"}

まとめ

通常関数は、さまざまな参照の仕方があるため汎用性があるが、thisの対象が実行の仕方によって変動してしまう。
一方、アロー関数は、参照するオブジェクトに制約があるものの、オブジェクトが決まっているため分かりやすい。

使用上の注意としては、

  • アロー関数を使うときは、間違ってオブジェクトのメソッドとして使わないようにする。
  • 通常関数を使うときは、thisが使い方によって変わることに気を付ける。

以上の2点でしょうか。

アロー関数で書くと格好よく書けるなー、としか思っていませんでした。
思った以上に様々な制約があり、他の違いもしっかり知っておく必要があると感じました。

最後に

通常関数とアロー関数の違いはthisの使い方だけではありません。
その他の違いについてはこちらをご覧ください。
JavaScript: 通常の関数とアロー関数の違いは「書き方だけ」ではない。異なる性質が10個ほどある。 - Qiita

初投稿で拙い文章となってしまいましたが、最後までお読みいただきありがとうございました。
何か誤り等ありましたらご指摘ください。

3
2
0

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
3
2