JavaScript ではおそらく switch 文を使う必要はない

JavaScript ではおそらく switch 文を使う必要はない

スイッチも複雑なコードブロックもありません

Switch は便利です。式を指定すると、それが case 節内の他の一連の式と一致するかどうかを確認できます。 次の例を考えてみましょう。

const name = "ジュリアナ";

スイッチ (名前) {
  ケース「ジュリアナ」:
    console.log("彼女はジュリアナです");
    壊す;
  ケース「トム」:
    console.log("彼女はジュリアナではない");
    壊す;
}

名前が「Juliana」の場合、メッセージを出力し、すぐにブロックから抜け出します。 switch 関数内では、case ブロック内で return を直接使用することで break を省略できます。

一致するものがない場合、デフォルトのオプションを使用できます。

定数名 = "クリス";

スイッチ (名前) {
  ケース「ジュリアナ」:
    console.log("彼女はジュリアナです");
    壊す;
  ケース「トム」:
    console.log("彼女はジュリアナではない");
    壊す;
  デフォルト:
    console.log("申し訳ございませんが、一致するものはありません");
}

Switch は、if を多く使用することを避けるために Redux リデューサーでも頻繁に使用されます (ただし、Redux Toolkit は定型文を少し簡略化します)。 次の例を考えてみましょう。

定数 LOGIN_SUCCESS = "LOGIN_SUCCESS";
LOGIN_FAILED は、次のようになります。

定数authState = {
  トークン: "",
  エラー: ""、
};

関数 authReducer(状態 = authState, アクション) {
  スイッチ(アクションタイプ){
    LOGIN_SUCCESSの場合:
      return { ...状態、トークン: action.payload };
    LOGIN_FAILEDの場合:
      return { ...状態、エラー: action.payload };
    デフォルト:
      状態を返します。
  }
}

これに何か問題があるでしょうか? ほとんどありません。しかし、もっと良い代替案はあるのでしょうか?

Pythonからのインスピレーション

Telmo からのこのツイートが私の注目を集めました。 彼は 2 つのスタイルの「スイッチ」を示しており、そのうちの 1 つは Python のパターンに非常に近いものです。

Python にはスイッチがないので、より良い代替手段が提供されます。 まず、コードを JavaScript から Python に移植してみましょう。

LOGIN_SUCCESS = "ログイン成功"
ログイン失敗 = "ログイン失敗"

auth_state = {"トークン": "", "エラー": ""}


auth_reducer を定義します(状態 = auth_state、アクション = {}):
    マッピング = {
        LOGIN_SUCCESS: {**state, "token": action["payload"]},
        LOGIN_FAILED: {**state, "error": action["payload"]},
    }

    マッピングを返す。get(アクション["type"], state)

Python では、辞書を使用してスイッチをシミュレートできます。 dict.get() は、スイッチのデフォルト ステートメントを表すために使用できます。

存在しないキーにアクセスすると、Python は KeyError エラーをトリガーします。

>>> my_dict = {

"名前": "ジョン",

"都市": "ローマ",

「年齢」: 44

}

>>> my_dict["ここにはない"]

# 出力: KeyError: 'not_here'

.get() メソッドはエラーを発生せず、存在しないキーにデフォルト値を指定できるため、より安全なアプローチです。

>>> my_dict = {

"名前": "ジョン",

"都市": "ローマ",

「年齢」: 44

}

>>> my_dict.get("not_here", "見つかりません")

# 出力: '見つかりません'

したがって、Python のこの行:

マッピングを返す。get(アクション["type"], state)

JavaScript での同等のものは次のとおりです。

関数 authReducer(状態 = authState, アクション) {
  ...
    デフォルト:
      状態を返します。
  ...
}

辞書を使用してスイッチを置き換える

前の例をもう一度考えてみましょう。

定数 LOGIN_SUCCESS = "LOGIN_SUCCESS";
LOGIN_FAILED は、次のようになります。

定数authState = {
  トークン: "",
  エラー: ""、
};

関数 authReducer(状態 = authState, アクション) {
  スイッチ(アクションタイプ){
    LOGIN_SUCCESSの場合:
      return { ...状態、トークン: action.payload };
    LOGIN_FAILEDの場合:
      return { ...状態、エラー: action.payload };
    デフォルト:
      状態を返します。
  }
}

スイッチを使わずにこれを行うことができます:

関数 authReducer(状態 = authState, アクション) {
  定数マッピング = {
    [LOGIN_SUCCESS]: { ...状態、トークン: action.payload },
    [LOGIN_FAILED]: { ...状態、エラー: action.payload }
  };

  マッピング[アクション.type] || 状態を返します。
}

ここでは、ES6 の計算プロパティを使用します。ここでは、マッピングのプロパティは、LOGIN_SUCCESS と LOGIN_FAILED の 2 つの定数に基づいてオンザフライで計算されます。
属性に対応する値は、ES9 (ECMAScript 2018) に由来するオブジェクト分解です。

定数マッピング = {
  [LOGIN_SUCCESS]: { ...状態、トークン: action.payload },
  [LOGIN_FAILED]: { ...状態、エラー: action.payload }
}

このアプローチについてどう思いますか?スイッチにはいくつかの制限があるかもしれませんが、リデューサーにとってはより良いソリューションかもしれません。

しかし、このコードはどのように動作するのでしょうか?

パフォーマンスはどうですか?

スイッチのパフォーマンスは辞書よりも優れています。次の例を使用してこれをテストできます。

console.time("サンプル");
(i = 0; i < 2000000; i++ とします) {
  const nextState = authReducer(authState, {
    タイプ: LOGIN_SUCCESS、
    ペイロード: "some_token"
  });
}
console.timeEnd("サンプル");

10回ほど測ってみると、

for t in {1..10}; do node switch.js >> switch.txt; 完了

for t in {1..10}; do node map.js >> map.txt; 完了

上記は、JavaScript で switch ステートメントを使用する必要がない理由の詳細です。JavaScript の switch ステートメントの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • JavaScript における 3 つの for ループ ステートメントの使用の概要 (for、for...in、for...of)
  • JavaScript ステートメントの一般的な for ループの詳細な説明
  • JavaScript の条件文の最適化手法の概要
  • Pythonでjsステートメントを実行する方法
  • JavaScriptステートメントを理解するのに役立つ記事

<<:  MySQLの指定順序ソートクエリについての簡単な説明

>>:  Mysql5.6.36 スクリプトのコンパイル、インストール、初期化のチュートリアル

推薦する

js でパズルゲームを実装する

この記事では、パズルゲームを実装するためのjsの具体的なコードを参考までに共有します。具体的な内容は...

XHTML CSSを使用して正式なブログを書く

ブログの正式名称は「Web log」で、中国語で「ネットワークログ」を意味します。後にブログに短縮さ...

nginx keepaliveの具体的な使い方

http1.1 プロトコルのデフォルトのリクエスト ヘッダーでは、図に示すように、デフォルトで ke...

HTML テーブルタグチュートリアル (35): 列間属性 COLSPAN

複雑なテーブル構造では、一部のセルが垂直方向に複数のセルにまたがるため、列間属性 COLSPAN を...

SSHパスワードフリーログイン設定方法の詳しい説明(画像とコマンド)

まず、私たちがやりたいことは、serverA の usera を使用して、パスワードなしで serv...

nginx + セカンダリドメイン名 + https サポートを使用する

ステップ1: Alibaba Cloudプライマリドメイン名にセカンダリドメイン名を追加する2 番目...

JPQLに基づく純粋なSQL文方式の詳細な説明

JPQL は Java Persistence Query Language の略です。 Java ...

タグが新しいページを開くかどうかという問題。主要ウェブサイトの開設状況をまとめました

a タグが新しいページを開くかどうか: (1)百度百科事典:ヘッダーが異なる場合は新しいページが開き...

JS が WeChat の「クソ爆弾」機能を実装

みなさんこんにちは、Qiufengです。最近、WeChatは新しい機能をリリースしました(WeCha...

ポップアップ効果を実現するにはjsを使用します

この記事の例では、ポップアップ効果を実現するためのjsの具体的なコードを参考までに共有しています。具...

CSS3 を使用したテキスト折り紙効果のサンプルコード

序文この記事では主に、CSS3 を使用してテキスト折り紙効果を実現する例を紹介します。これは、参考と...

MySQLクエリが遅い理由

目次1. 遅いところはどこですか? 2. 不要なデータをクエリしましたか? 1. 不要なレコードをク...

MySQLのスレッド実行の急増とクエリの遅延の問題を解決する

目次背景問題の説明原因分析CPUクエリが遅い接続数分析する拡大する総括する背景新年を迎える前は、一年...

jQuery カスタム虫眼鏡効果

この記事の例では、jQueryのカスタム虫眼鏡効果の具体的なコードを参考までに共有しています。具体的...

Linux での Firewalld の高度な設定の使用に関する詳細な説明

IPマスカレードとポート転送Firewalldは2種類のネットワークアドレス変換をサポートしています...