JavaScriptに関するお知らせ

SINCE2019
>
【JS】アロー関数の戻り値がObjectの時に()が必要な理由を詳しく解説

【JS】アロー関数の戻り値がObjectの時に()が必要な理由を詳しく解説


こんにちは!今日はアロー関数のちょっとしたポイントについてです。

戻り値がオブジェクトだと()が必要

アロー関数は戻り値がオブジェクトだと()が必要です、こんな感じ。

const foo = () => ({
  one: 1,
  two: 2,
})

()がないとエラーになるわ。

const foo = () =>
  {
    one: 1,
    two: 2,
  }// error!

一方、戻り値が配列なら()はあってもなくてもいいのよ。

const foo = () => [1, 2] // ok!

あとアロー関数以外でも()は不要。

const foo = function () {
  return {
    one: 1,
    two: 2,
  }
} // ok!

なぜ()がいるのか

アロー関数だと{}がオブジェクトかスコープかわからんからです。

下の例を見てみて。

const foo = () => {
  return 'one'
}

この{}はスコープです。つまり、「関数fooはここからここまで!」って示してるんですね:) この関数では'one'をreturnするみたいです。

次にこれをどうぞ。どのような挙動になるでしょう?

const foo = () => {
  'one'
}

答えは何も返ってきません。これはjavascriptをそこそこ知ってる人の方が混乱するかも。なぜなら...

key: valueの省略

javascriptのオブジェクトはkeyとvalueが同じ時片方のみの記述でokって仕様があります(最近追加された仕様です)。

例えば下の2つは両方とも同じ挙動。(fooは引数をそのまま返す関数)

const foo = n => n
const ans = foo({
  one: 'one',
})

console.log(ans.one) // one

const foo = n => n
const ans = foo({
  'one'
})

console.log(ans.one)// one

これを踏まえた上でさっきの例を見ると...

const foo = () => {
  'one'
}

あたかも{'one': 'one'}のオブジェクトがreturnされるかのような印象を受けますね!これが非常にややこしい。

「式があるだけ」に注意

もう少し違う例を見てみましょう。下の関数ではどうなるでしょう?

const foo = () => {
  'one'
  return 'two'
}

returnされるのは'two'です!これはわかる。でも、上の'one'は何!?

この'one'はいわば「あるだけ」です。'one'は文字列として評価されますがそれで終わり。特に何もしません。

'one'の代わりに計算式とかだとより分かりやすいかも↓

const foo = () => {
  1
  1 + 1
  1 + 1 === 2
  return 42
}

これも42が返るだけですわ。

つまり、前述の例は...

const foo = () => {
  'one'
}

{}はスコープと見なされ、oneはただあるだけ!ってことです:)だから何も返って来ないんですねー

{}をオブジェクトだと評価させる

要は{}がスコープじゃなくてオブジェクトだよって評価させればよいのです。

その結果として()で括るのが手っ取り早いってことですね!!

const foo = () => ({
  one: 1,
  two: 2,
})

式において{}は基本的にオブジェクト

ただ、{}は式の中では基本的にオブジェクトです。=>の直後だとスコープになるけどな!

なので、{}を式中、かつ=>の直後以外なら問題ないわけです。これを利用すると...

const foo = () =>
  true && {
    one: 1,
    two: 2,
  }

こんな風にも書けます。ちょっと前に書いたconsole.logは戻り値が無いのでもっと使いやすい関数を作るとかはこの挙動を利用してますねーこんな感じに!

const foo = value =>
  console.log(value) && {
    key: value,
  }

おわりに

アロー関数は戻り値がObjectの時に()必要ってのはわりと有名ですが、その理由も併せて覚えとくと 身に付きやすいなーってのが言いたかったです。

高校生の時の世界史の先生が「年号は丸暗記するんじゃなくてその次代の背景とかもセットで覚えるといいんだよー」って言ってたけどやっと先生の言いたいこと今ならよく分かるまじで

以上!



PREV
2019-05-23
【JS】Promiseで書かれたAjaxをasync/awaitに書き直す

NEXT
2019-06-29
【JS】Vueの:classの書き方3通り