Il existe quatre façons d'écrire un commutateur JavaScript, le savez-vous ? Que vous le sachiez ou non, je ne sais pas.
À ma connaissance, il n'existe qu'une seule façon d'écrire l'instruction switch JavaScript. Mais lorsqu’il s’agit de gérer des branches, il existe de nombreuses façons de les écrire. La méthode d'écriture de branche if peut être comptée pour une, la méthode d'écriture de branche switch peut être comptée comme la deuxième et la troisième consiste à utiliser le mode stratégie. Si les opérateurs conditionnels sont également inclus, eh bien, il y en a exactement quatre.
mais le protagoniste de cet article est Switch. Tout le monde sait que switch est généralement écrit sous la forme d'une variable ou d'une expression switch et d'une constante de cas. Eh bien, par exemple, pour un score de cent points, 90 et plus sont considérés comme excellents, 80 et plus et moins de 90 sont considérés comme bons, 60 et plus et moins de 80 sont considérés comme qualifiés et moins de 60 sont considérés comme non qualifiés. serait probablement écrit comme ceci :
function calcGrade(score ) { ligne const = score / 10 | commutateur (ligne) { cas 10 : cas 9 : renvoyer « Excellent » ; cas 8 : rendre le bien"; cas 7 : cas 6 : renvoyer « qualifié » ; défaut: renvoyer « non qualifié » ; } }
Dans le code, score / 10 | 0
a le même effet que Math.floor(score / 10)
, qui consiste à diviser par 10 pour obtenir la partie entière du quotient.
Ce commutateur est assez bien utilisé, et la méthode d'arrondi pour éviter d'utiliser une longue liste de branches if...else est également une astuce astucieuse.
Mais maintenant, les règles ont changé et le point de séparation entre qualifié et bon a été abaissé de 80 points à 75 points. Que devons-nous faire ?
La méthode d'arrondi ci-dessus est toujours possible, mais cette fois le diviseur n'est plus 10, mais 5. En conséquence, il y a beaucoup plus de cas :
Il est préférable d'utiliser 9 cas. si... sinon.
Est-ce? En fait, il existe un moyen plus simple d'écrire en utilisant switch :
function calcGrade(score) { changer (vrai) { score de cas >= 90 : renvoyer « Excellent » ; score de cas >= 75 : rendre le bien"; score de cas >= 60 : renvoyer « qualifié » ; défaut: renvoyer « non qualifié » ; } }
Est-ce que cela vous semble un peu étrange ? Ce n'est pas du tout la constante de cas d'expression de commutation habituelle, mais exactement le contraire, l'expression de cas de constante de commutation ! Si vous prenez ce programme et l’exécutez, vous constaterez qu’il n’y a aucun problème. Parce que - switch et case correspondent selon ===
, peu importe qu'il s'agisse d'une expression ou d'une constante, ou en d'autres termes, switch et case peuvent être suivis d'une expression !
Oui, expression !
Ainsi, dans l'exemple ci-dessus, changer switch(true)
switch( 2 > 1)
a le même effet.
D'accord, mon esprit est ouvert. Peu importe le nombre de façons dont vous pouvez écrire switch. La prochaine chose à examiner est la variante Switch.
: j'ai vu que C# avait une expression switch, et je suis jaloux. Peut-elle être implémentée ?
Ne vous inquiétez pas, tout en JavaScript peut être une expression... Sinon, utilisez simplement IIFE pour encapsuler une
fonction calcGrade(score) { retour (valeur => { changer (vrai) { valeur de cas >= 90 : renvoyer « Excellent » ; valeur de cas >= 75 : rendre le bien"; valeur de cas >= 60 : renvoyer « qualifié » ; défaut: renvoyer « non qualifié » ; } })(score); }
Notez que score
est utilisé ici comme paramètre d'IIFE car, en utilisation réelle, une expression peut devoir être transmise. Dans ce cas, elle doit être évaluée au préalable et une seule fois (pour éviter les effets secondaires de substitution).
Cependant, une telle encapsulation n'a évidemment aucun sens. Si vous voulez vraiment l'encapsuler comme ceci, il est préférable de l'encapsuler comme une stratégie :
function calcGrade(score) {. return ((valeur, règles) => règles.find(({ t }) => t(valeur)).v)( score, [ { t : n => n >= 90, v : "Excellent" }, { t : n => n >= 75, v : "Bon" }, { t : n => n >= 60, v : "Qualifié" }, { t : () => vrai, v : "non qualifié" }, ] ); }
Chaque stratégie est un objet contenant un testeur ( t
) et une valeur ( v
). tester est une fonction de jugement qui transmet la valeur qui doit être jugée, qui est l'expression ici dans switch (表达式)
, et cette expression est également transmise en tant que paramètre d'IIFE après avoir été évaluée à l'avance. Le processus d'application d'une stratégie est simple et grossier, il s'agit de trouver la première stratégie qui remplit les conditions et d'en retirer la valeur.
Bien sûr, cette stratégie est un peu exagérée. Lorsque vous avez vraiment besoin d’utiliser une stratégie, celle-ci n’est généralement pas une valeur, mais un comportement, c’est-à-dire une fonction.
Nous savons que dans l'instruction switch, chaque cas est dans la même portée, donc la même variable locale ne peut pas être déclarée dans deux instructions case. Bien que l'encapsulation avec { }
puisse résoudre ces problèmes, le code n'a pas l'air très bon, surtout faites attention à ne pas oublier break
. Si vous utilisez une stratégie, elle peut paraître agréable à l'œil et vous n'avez pas à vous soucier du problème de rupture :
ici à des fins de démonstration, dans le comportement de la stratégie, les résultats seront d'abord affichés, puis le niveau sera est revenu.
fonction calcGrade(score) { return ((valeur, règles) => règles.find(({ t }) => t(valeur)).fn(valeur))( score, [ { t : n => n >= 90, fn : score => { note const = « Excellent » ; console.log(note, score); note de retour ; } }, { t : n => n >= 75, fn : score => { note const = « bon » ; console.log(note, score); note de retour ; } }, { t : n => n >= 60, fn : score => { note const = "réussi" ; console.log(note, score); note de retour ; } }, { t : () => vrai, fn : score => { const grade = « non qualifié » ; console.log(note, score); note de retour ; } }, ] ); }
Le code est effectivement un peu long car il contient une logique de comportement stratégique. Si elle doit vraiment être utilisée comme expression de commutation, la partie stratégie doit être une expression, pas trop longue. Dans le code ci-dessus, le comportement de la stratégie est similaire et peut être encapsulé dans une fonction, de sorte qu'il puisse être écrit sous la forme d'une expression :
function calcGrade(score) { const printGrade = (note, score) => { console.log(note, score); note de retour ; } ; return ((valeur, règles) => règles.find(({ t }) => t(valeur)).fn(valeur))( score, [ { t : n => n >= 90, fn : score => printGrade("Excellent", score) }, { t : n => n >= 75, fn : score => printGrade("Bon", score) }, { t : n => n >= 60, fn : score => printGrade("qualifié", score) }, { t: () => true, fn: score => printGrade("non qualifié", score) }, ] ); }
Est-ce que ça a l'air présentable maintenant ?
Les codes ci-dessus ont des formes différentes et font des choses similaires, et il n'y a aucune comparaison pour savoir lequel est le meilleur. Peu importe ce que vous aimez, vous êtes élégant ; peu importe ce que vous n’aimez pas, vous n’êtes pas favorisé. Dans différentes situations, choisissez simplement l'approche appropriée. Le code ci-dessus utilise find()
pour trouver la stratégie. Si filter()
est utilisé à la place, ce sera une autre histoire.