結論から(比較表)
観点 |
function 構文 |
アロー関数 (=> ) |
---|---|---|
this の扱い | 呼び出し元に応じて動的に決まる | 定義時の外側の this を固定的に使う |
arguments 使用可否 | ✅ 使用可能 | ❌ 使用不可(代わりに ...args を使う) |
new での生成 | ✅ コンストラクタとして使える | ❌ new できない |
構文の簡潔さ | やや冗長 | ✅ 簡潔に書ける |
return の省略 | ❌ 必ず書く必要がある | ✅ 単一式なら省略可能 |
使いどころ | メソッド、イベント、クラスメソッドなど | コールバック、短い関数、非同期処理など |
1.thisの扱いについて
this
の扱いはfunctionとアロー関数で異なります。
functionの場合
functionで定義した関数のthis
は呼び出しもとで動的に変わります。
test.js
param = 'global param' //グローバル変数
function func() {
console.log('function:', this.param)
}
obj = {
param: 'local param',
func: func
}
obj.func() //'function: local param'
func() //'function: global param'
アロー関数の場合
test2.js
param = 'global param'
const arrow = () => {
console.log('arrow:', this.param)
}
obj = {
param: 'local param',
arrow: arrow
}
obj.arrow() //undefined
arrow() //undefined
あれ?アロー関数ではどちらもundefined
になっていますね。
実はこれJavaScriptの仕様でthis
はglobalThis
に移行しました。
補足:thisとglobalThis
トップレベルでconst
,let
,var
をつけずに定義した変数はグローバル変数と呼ばれ、グローバルオブジェクトに格納されます。
Node.jsではグローバルオブジェクトはthis
ではなくglobalThis
に変更されました。(ブラウザではどちらもWindowオブジェクトを指します。)
test3.js
params = 'global param'
console.log('this:', this) //{}
console.log('globalThis:', globalThis) //...省略, param: 'global param'
話を戻すと、、、
アロー関数の挙動を調べるにはthis
のパラメータを定義すれば良さそうですね!
test2.jsを変更
test2.js
this.param = 'global param' //thisというオブジェクトにparamを格納
const arrow = () => {
console.log('arrow:', this.param)
}
obj = {
param: 'local param',
arrow: arrow
}
obj.arrow() //'arrow: global param'
arrow() //'arrow: global param'
アロー関数では呼び出し方に関わらずthis
オブジェクトが参照されることがわかりました。
2.arguments オブジェクトの違い
test4.js
function func() {
console.log(arguments) // 利用可能
}
const arrow = () => {
console.log(arguments) // 利用不可
}
func(1,2,3) // [Arguments] {'0': 1, '1': 2, '2': 3}
arrow(1,2,3) //グローバルargumentsが参照される
アロー関数では、代わりに残余引数が使えます。
test5.js
function func(...arguments) {
console.log(arguments) // 利用可能
}
const arrow = (...arguments) => {
console.log(arguments) // 利用可能
}
func(1,2,3) // [1, 2, 3]
arrow(1,2,3) // [1, 2, 3]
3.コンストラクタとして使えるか
test6
function Person(name) {
this.name = name
console.log(this.name)
}
const p = new Person("Yuta") // 'Yuta'
const ArrowPerson = (name) => {
this.name = name
console.log(this.name)
};
// const p2 = new ArrowPerson("Yuta") //TypeError: ArrowPerson is not a constructor
4.returnの省略
test7.js
function add(a, b) {
return a + b
}
const add2 = (a, b) => a + b
アロー関数はブロック{}
を使わない場合、暗黙的にreturn
になります。
使い分け早見表
シーン・目的 | おすすめ構文 | 理由・補足説明 |
---|---|---|
オブジェクトのメソッドを定義する | function |
this がオブジェクト自身を指すため。アロー関数だと this がズレる |
クラスのメソッド | function |
this や super を使いたいから |
コンストラクタ(newする関数) | function |
アロー関数は new できないため |
コールバック(配列操作、非同期) | アロー関数 |
this に影響されず、短く書けて可読性が高い |
短い関数や一時的な処理 | アロー関数 |
return を省略でき、コードが簡潔になる |
イベントリスナー(thisを使いたい) | function |
this がイベント発生元(DOM要素)になる |
クロージャの中で this を固定したい |
アロー関数 | 外側の this を引き継げるから(例:React内の関数など) |
まとめ
functionとアロー関数の違いをまとめてみました。他にも細かい違いはあるのですが本記事では割愛します。興味ある方は調べてみてください。