かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript switch 文の中でも const したい!

React の useReducer を使うとき action ごとの処理を分けるのに switch 文を使うことが多いですが、複数の case 内で同じ名前の変数を使いたい時 const で定義するとハマってしまうことがあります。

case 内で同じ名前の変数を const で定義するとエラーになる

例えば次のような reducer を作った時、 case 'DELETE' 内で id は既に定義済みというエラーが発生します。

const reducer = (state, action) => {
  switch(action.type) {
    case 'CREATE':
      const { id, title } = action;
      return [...state, {id, title}];
    case 'DELETE':
      const { id } = action;
      return state.filter((item) => item.id !== id);
    default:
      return false;
  }
};

=> Parsing error: Identifier 'id' has already been declared 😇

switch 文の case 節はスコープを作らない

理由はシンプルで case 節はブロックではないのでスコープを作らないからです。

this is due to both let statements being interpreted as duplicate declarations of the same variable name within the same block scope.
cf. switch - JavaScript | MDN

switch 文内で変数定義を const でするなら case 節を {} で囲えばOK

const reducer = (state, action) => {
  switch(action.type) {
    case 'CREATE': {
      const { id, title } = action;
      return [...state, {id, title}];
    }
    case 'DELETE': {
      const { id } = action;
      return state.filter((item) => item.id !== id);
    }
    default:
      return false;
  }
};

こうすると、case 節内がそれぞれ別のスコープになるので、同じ変数名を const で定義できるようになる。✌️₍ ᐢ. ̫ .ᐢ ₎✌️ ヤッタネ.
block statement と呼ぶらしい cf. block - JavaScript | MDN

まとめ

文 ( statement ) はスコープを作る。
節 ( clause ) はスコープを作らない。

みたいな認識で良いのかな?


[参考]

Nintendo Switch あつまれ どうぶつの森セット

Nintendo Switch あつまれ どうぶつの森セット

  • 発売日: 2020/03/20
  • メディア: Video Game
最近のSNS switch 持ってないと人権がない感…