
JavaScript スイッチの書き方には 4 つの方法があるのをご存知ですか?あなたがそれを知っているかどうかはわかりません。
私が知っている JavaScript の switch ステートメントを記述する方法は 1 つだけです。ただし、ブランチの処理に関しては、さまざまな記述方法があります。 if 分岐の書き込み方法は 1 つ目、switch 分岐の書き込み方法は 2 つ目、そして 3 つ目はストラテジ モードを使用する方法です。条件演算子も含めると、ちょうど 4 つになります。
が、この記事の主人公はスイッチです。 switch は通常、switch 変数または式とケース定数として記述されることは誰もが知っています。たとえば、100 点のスコアの場合、90 以上が優秀、80 以上 90 未満が良好、60 以上 80 未満が合格、60 未満が不合格とみなされます。おそらく次のように書かれるでしょう:
function calcGrade(score ) {
const 行 = スコア / 10 |
スイッチ (行) {
ケース 10: ケース 9:
「素晴らしい」を返します。
ケース8:
「良い」を返します。
ケース 7: ケース 6:
「適格」を返します。
デフォルト:
「不適格」を返します。
}
コードでは、 score / 10 | 0 Math.floor(score / 10)と同じ効果を持ち、商の整数部分を取得します。
このスイッチは非常にうまく使用されており、if...else 分岐の長いリストの使用を避けるための丸め方法も賢いトリックです。
しかし、ルールが変更され、資格と優良の分かれ目は 80 点から 75 点に引き下げられました。どうすればよいでしょうか。
上記の四捨五入方法は引き続き可能ですが、今回は約数が 10 ではなく 5 になります。同様に、
つのケースを使用することをお勧めします。もし...そうでなければ。
?実際、スイッチを使用して記述するより簡単な方法があります。
function calcGrade(score) {
スイッチ (真) {
ケーススコア >= 90:
「素晴らしい」を返します。
ケーススコア >= 75:
「良い」を返します。
ケーススコア >= 60:
「適格」を返します。
デフォルト:
「不適格」を返します。
}
}ちょっと変な感じがしますか?これは通常の switch 式の case 定数ではなく、まったく逆の switch 定数の case 式です。このプログラムを実行してみると、まったく問題がないことがわかります。 - switch と case は===に従って照合されるため、それが式であるか定数であるかは関係ありません。つまり、switch と case の後に式を続けることができます。
はい、表現です!
したがって、上記の例では、 switch(true) switch( 2 > 1)変更しても同じ効果があります。
わかった、私の心は開いている。 switch をいくつの方法で記述できるかは関係ありません。次に注目すべきはスイッチのバリエーションです。
: C# に switch 式があるのを見たので、実装できるでしょうか?
心配しないでください。JavaScript ではすべてを式にすることができます。そうでない場合は、IIFE を使用して 1 つの
関数 calcGrade(score) {をカプセル化してください。
return (値 => {
スイッチ (真) {
ケース値 >= 90:
「素晴らしい」を返します。
ケース値 >= 75:
「良い」を返します。
ケース値 >= 60:
「適格」を返します。
デフォルト:
「不適格」を返します。
}
})(スコア);
実際の使用では式を渡す必要がある場合があるため、ここではscoreが IIFE のパラメータとして使用されていることに注意してください
。
この場合、事前に 1 回だけ評価する必要があります (置換による副作用を避けるため)。
ただし、このようなカプセル化は明らかに意味がありません。本当にこのようにカプセル化したい場合は、次のように戦略としてカプセル化することをお勧めします
。
return ((値, ルール) => rules.find(({ t }) => t(値)).v)(
スコア、
[
{ t: n => n >= 90、v: "優れた" }、
{ t: n => n >= 75、v: "良い" },
{ t: n => n >= 60、v: "適格" }、
{ t: () => v: "非修飾" },
】
);
各ストラテジは、
テスター ( t ) と値 ( v ) を含むオブジェクトです。 tester は判定したい値を渡す判定関数で、ここではswitch (表达式)の式ですが、この式も事前に評価された上で IIFE のパラメータとして渡されます。戦略を適用するプロセスは単純かつ大雑把で、条件を満たす最初の戦略を見つけてその価値を取り出すというものです。
もちろん、この戦略は少しやりすぎです。本当に戦略を使用する必要がある場合、その戦略は通常、値ではなく動作、つまり関数です。
switch ステートメントでは、各 case が同じスコープ内にあるため、2 つの case ステートメントで同じローカル変数を宣言できないことがわかっています。 { }で囲むとこれらの問題は解決できますが、コードの見栄えはあまり良くありません。特に、 break忘れないように注意してください。ストラテジーを使用すると、見た目は楽しくなり、ブレークの問題を心配する必要はありません。
ここではデモンストレーションを目的として、ストラテジーの動作では、最初に結果が出力され、次にレベルが出力されます。戻ってきました。
関数 calcGrade(スコア) {
return ((値, ルール) => rules.find(({ t }) => t(値)).fn(値))(
スコア、
[
{
t: n => n >= 90、
fn: スコア => {
const グレード = "優秀";
console.log(成績、スコア);
成績を返す。
}
}、
{
t: n => n >= 75、
fn: スコア => {
const グレード = "良い";
console.log(成績、スコア);
成績を返す。
}
}、
{
t: n => n >= 60、
fn: スコア => {
const グレード = "合格";
console.log(成績、スコア);
成績を返す。
}
}、
{
t: () => true、
fn: スコア => {
const グレード = "不適格";
console.log(成績、スコア);
成績を返す。
}
}、
】
);
戦略的な動作ロジックが含まれているため、
コードは確かに少し長くなります。本当に switch式として使用する場合、戦略部分は長すぎない式にする必要があります。上記のコードでは、戦略の動作は同様であり、関数にカプセル化できるため、式の形式で記述することができます。
function calcGrade(score) {
const printGrade = (成績, スコア) => {
console.log(成績、スコア);
成績を返す。
};
return ((値, ルール) => rules.find(({ t }) => t(値)).fn(値))(
スコア、
[
{ t: n => n >= 90, fn: スコア => printGrade("Excellent", スコア) },
{ t: n => n >= 75, fn: スコア => printGrade("Good", スコア) },
{ t: n => n >= 60, fn: スコア => printGrade("qualified", スコア) },
{ t: () => true, fn: スコア => printGrade("unqualified", スコア) },
】
);
見栄えが良くなりましたか
?
上記のコードは形式は異なりますが、同様のことを実行するため、どちらが優れているかを比較することはできません。何が好きでも、何が嫌いでも、あなたはエレガントです。さまざまな状況に応じて、適切なアプローチを選択してください。上記のコードでは、 find()使用して戦略を見つけます。代わりにfilter()を使用する場合は、話は異なります。