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 スクリプトのコンパイル、インストール、初期化のチュートリアル

推薦する

MySQLとRedisキャッシュ間の同期ソリューションについての簡単な説明

目次1. ソリューション 1 (UDF)デモケース2. ソリューション2(binlogの解析)キャナ...

MySQL学習データベース操作DML初心者向け詳細解説

目次1. ステートメントを挿入する1.1 行を挿入する1.2 複数行を挿入する1.3 クエリステート...

パーティショニングを使用して数十億のデータに対する MySQL データ処理を最適化する方法

MySQL が数千万のデータをクエリする場合、ほとんどのクエリ最適化の問題はインデックスを通じて解決...

MySQL テーブルがロックされているかどうかを照会する方法

具体的な方法: (推奨チュートリアル:MySQLデータベース学習チュートリアル)テーブルロックの状態...

Tomcat が https アクセスをサポートするための手順の説明

tomcat を https アクセスに対応させる方法ステップ: (1)キーストアファイルを生成する...

MySQLはIDに適切なデータ型を選択します

目次分散IDソリューションの概要データベース自動増分IDデータベースマルチマスターモード数値セグメン...

XHTML チュートリアル、XHTML の基礎を簡単に紹介します

<br />この記事では、XHTMLとXHTMLの基礎知識について簡単に紹介します。 X...

MySQL の悲観的ロックと楽観的ロックの使用例

悲観的ロック悲観的ロックは、データを悲観的であるとみなします。データをクエリするときに、ロックを追加...

Tomcatのクラスロードメカニズムを説明する記事

目次- 序文 - - JVM クラスローダー - 1. JVMクラスローダー2. クラスローダーのソ...

Linux サーバーに SSH パスワードなしでログインする方法

テスト サーバーにログインするたびに、必ず ssh ログインのパスワードを入力する必要があります。ロ...

Linux 3.X/4.x/5.x でパゴダ パネルのパスワードを忘れた場合の解決方法

ssh に入り、次のコマンドを入力してパスワードをリセットします (コマンドの末尾の「testpas...

全体的なユーザーエクスペリエンスを確保する方法

関連記事:ユーザーエクスペリエンスのためのウェブサイトデザイン今朝、GMail がまた不調になり、接...

この記事は、Dockerにおけるcgroupの具体的な使用法を徹底的に理解するのに役立ちます。

目次cgroupとはcgroupの構成cgroupが提供する機能cgroup 内の CPU を制限す...

Web2.0: 情報過多の原因と解決策

<br />情報の重複、情報過多、情報強迫、パーソナライズされたカスタマイズ、検索エンジ...