TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Using the switch(true) pattern in JavaScript

120 pointsby seanbarryabout 4 years ago

25 comments

kvczorabout 4 years ago
I prefer early return pattern.<p>Which would look like this:<p><pre><code> const user = { firstName: &quot;Seán&quot;, lastName: &quot;Barry&quot;, email: &quot;my.address@email.com&quot;, number: &quot;00447123456789&quot;, }; if (!user) { throw new Error(&quot;User must be defined.&quot;); } if (!user.firstName) { throw new Error(&quot;User&#x27;s first name must be defined&quot;); } if (typeof user.firstName !== &quot;string&quot;) { throw new Error(&quot;User&#x27;s first name must be a string&quot;); } return user;</code></pre>
评论 #26780226 未加载
评论 #26780768 未加载
评论 #26782806 未加载
评论 #26780107 未加载
评论 #26785264 未加载
评论 #26784892 未加载
评论 #26780640 未加载
评论 #26784852 未加载
评论 #26780019 未加载
评论 #26780443 未加载
评论 #26786779 未加载
评论 #26785951 未加载
评论 #26784326 未加载
评论 #26780212 未加载
elyseumabout 4 years ago
A good example of: just because you can, it doesn’t mean you should. Yes, the if&#x2F;else sequence is a bit more unstructured in terms of code layout, but chances the next developer browsing the code will instantly know what it does will be much higher.
评论 #26779866 未加载
评论 #26779990 未加载
评论 #26785810 未加载
vikingcaffieneabout 4 years ago
I’d flag this if it came up in PR. It’s clever and novel which is precisely why it’s a bad idea. Always bet on boring.
评论 #26780093 未加载
评论 #26779996 未加载
hargabout 4 years ago
I think the post doesn&#x27;t give a fair comparison as in the if&#x2F;else case there&#x27;s no need to use &quot;else&quot; blocks if you&#x27;re throwing an error or returning. In this case I think simple &quot;if&quot; statements are cleaner and certainly more &quot;normal&quot;.<p>E.g.<p><pre><code> if (!user) { throw new Error(&quot;User must be defined.&quot;); } if (!user.firstName) { throw new Error(&quot;User&#x27;s first name must be defined&quot;); } return user;</code></pre>
评论 #26780987 未加载
评论 #26780623 未加载
jacknewsabout 4 years ago
Is this a real thing? It looks incredibly hacky to me. What happens when multiple cases are true, are they all handled? In what order? What happens if one of them returns? Etc.
评论 #26780196 未加载
scotttrinhabout 4 years ago
Hopefully we will get real pattern-matching at some point (<a href="https:&#x2F;&#x2F;github.com&#x2F;tc39&#x2F;proposal-pattern-matching" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;tc39&#x2F;proposal-pattern-matching</a>), but I kinda sorta like this!
graderjsabout 4 years ago
Guaranteed to always occur:<p><pre><code> ... case !isValidPhoneNumber(user.email): ... </code></pre> Tho see [1] and [2]<p>[1]: <a href="https:&#x2F;&#x2F;github.com&#x2F;kdeldycke&#x2F;awesome-falsehood#emails" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;kdeldycke&#x2F;awesome-falsehood#emails</a><p>[2]: <a href="https:&#x2F;&#x2F;github.com&#x2F;kdeldycke&#x2F;awesome-falsehood#phone-numbers" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;kdeldycke&#x2F;awesome-falsehood#phone-numbers</a>
评论 #26780539 未加载
评论 #26780734 未加载
erikeriksonabout 4 years ago
Validation code as shown tends to be repetitive and imperfectly implemented. I have found that transitioning to using AJV and JSON Schema is far more sustainable, especially on an API surface. One describes the data and depends on consistent and vetted logic for validating the described types rather than repetitively describing how to validate them.<p>Validations that happened at an application level must still be written but those tend to be specific to the application logic or system state. An example of logic related validation is contingently valid argument values where the compatibility of one value being used with another must be tested. An example of state related validation is a constraint that a given value must exist in a dynamic table.
aastronautabout 4 years ago
This style gets the label &#x27;poor-mans-pattern-matching&#x27; from me. If pattern matching would not be in my daily vocabulary, as it&#x27;s also not available in JS, I&#x27;d consider it a misuse of switch&#x2F;case and this post also makes an odd example for its usefulness.<p>The example I would pick is the following: Consider you need to switch depending on a version (of a specification in my case), but this version isn&#x27;t represented as an enum in the codebase, but as a number instead. So our team had something like this in the codebase (early return):<p><pre><code> function foobar(version: number): string { if (version === 3.1 || version === 3) { return &#x27;result_3&#x27;; } if (version &lt; 2 &amp;&amp; version &gt;= 1) { return &#x27;result_1&#x27;; } if (version &gt;= 2) { return &#x27;result_2&#x27;; } throw new Error(`Cannot interpret version &#x27;${version}&#x27;`); } </code></pre> I read it as &quot;people don&#x27;t care about branching order that much, so how can I make my wish for better readability more clear?&quot;.... my end goal then was to bring it into this state (a distinct enum as discrete value of the version):<p><pre><code> enum Version { _1_1 = 1.1, _2 = 2, _3 = 3, _3_1 = 3.1, }; function foobar(version: Version): string { switch (version) { case Version._3_1: case Version._3: return &#x27;result_3&#x27;; case Version._2: return &#x27;result_2&#x27;; case Version._1_1: return &#x27;result_1&#x27;; default: (function (val: never): never { throw new Error(`Exhaustiveness reached: ${val}`); })(version); } } </code></pre> ...and my interim solution that made it into the PR in time turned out to be something like this (switch true):<p><pre><code> function foobar(version: number): string { switch (true) { case version &gt;= 3: return &#x27;result_3&#x27;; case version &gt;= 2: return &#x27;result_2&#x27;; case version &gt;= 1: return &#x27;result_1&#x27;; default: throw new Error(`Cannot interpret version &#x27;${version}&#x27;`); } } </code></pre> My PR was flagged by the team for misuse of the switch statement, we had some discussion and I changed it back to the simple if&#x2F;else branching from above.
评论 #26784366 未加载
评论 #26804003 未加载
Sophistifunkabout 4 years ago
Good lord this is awful. If somebody&#x27;s paying you to solve problems with code, please just write clear code, rather than showing off. Somebody&#x27;s going to have to make sense of it a year from now when requirements change, and you will be in a sense talking to that future programmer (maybe it&#x27;s you) via code. You should be trying to tell them about the problem, rather than about yourself.
molszanskiabout 4 years ago
In addition to an already mentioned early return pattern, I also often recommend switching from switch to pattern matching via an object.<p>It has an additional benefit of extracting code into data structures or making them parametric<p><pre><code> function getArrow(direction) { switch (direction) { case &quot;left&quot;: return &quot;&lt;--&quot; case &quot;righ&quot;: return &quot;--&gt;&quot; default: return &quot;¯\\_(ツ)_&#x2F;¯&quot; } } function getArrow(direction) { const arrows = { left: &quot;&lt;--&quot;, right: &quot;--&gt;&quot;, default: &quot;¯\\_(ツ)_&#x2F;¯&quot;, } let arrow = arrows[direction] if (arrow) { return arrow } else { return arrow.default } }</code></pre>
评论 #26787330 未加载
standardUserabout 4 years ago
On a similar topic, I&#x27;m wondering how often people are using the &quot;else&quot; part of if&#x2F;else these days. I haven&#x27;t written &quot;else&quot; in years and I&#x27;ve become very fond of that &quot;if only&quot; pattern.
评论 #26784297 未加载
评论 #26787371 未加载
评论 #26783887 未加载
jimjimjimjimabout 4 years ago
I think the beauty of the switch statement is that when you see one you know you&#x27;re just concentrating on the value of one variable. I think the if else if is actually cleaner for the user example in the post.
1_playerabout 4 years ago
That&#x27;s good and dandy until one changes one case block to normal statements instead of a terminating one, forgets to add a &quot;break;&quot; and someone has a nightmare debugging session trying to figure what is going on.<p>Go did good by making case blocks break automatically and requiring the &quot;fallthrough&quot; keyword in one of those very rare cases you need it do.
borishnabout 4 years ago
The article is misleading, in implying that `switch(true)` is a special case: &quot;The fundamental principle of the switch true pattern is that you can match against expressions as well as values.&quot;<p>It should be states as &quot;The fundamental principle of the switch pattern in JavaScript is that you can match against expressions as well as values.&quot;<p>From <a href="https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Reference&#x2F;Statements&#x2F;switch" rel="nofollow">https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Refe...</a>:<p>A switch statement first evaluates its expression. It then looks for the first case clause whose expression evaluates to the same value as the result of the input expression
encodererabout 4 years ago
For many years I stopped using this after getting flack in pull requests.<p>I’ve recently added it back into my toolkit and am reminded how much I love it. Don’t over use it but there are some really gnarly if&#x2F;else blocks that can be expressed beautifully with a switch and fall-thru.
评论 #26783861 未加载
mwkaufmaabout 4 years ago
Even accepting the dubious premise that &quot;pretty text = maintainable code&quot;, he&#x27;s juked his exampled by (i) littering the simple early-outs with unnecessary &quot;else&quot;s and (ii) stripping the &quot;break&quot;s from his switch.
评论 #26804935 未加载
jypepinabout 4 years ago
I remember when I first discovered the concept of pattern matching, I tried to find a way to &quot;hack&quot; the switch statement in js to make it work like pattern matching.<p>The switch(true) format was the closest I got to it, which I personally don&#x27;t like compared to a clean if&#x2F;else or early return.<p>There&#x27;s probably some performance differences between if&#x2F;else and switch (I haven&#x27;t checked) but it probably end up being what&#x27;s your preference &#x2F; what standard code style you want to enforce on your team.
dvirskyabout 4 years ago
Reminds me of a C++ pattern some guy I worked with years ago used to love to simplify complex if checks - using do...while(false) to create a scope you can easily break out of. e.g.<p><pre><code> bool success = false; do { if (!someCondition) break; if (!otherCondition) break; ... success = true; } while(false); if (!success) { ... } </code></pre> I personally disliked it, plus it can lead to funky behavior under optimization.
评论 #26786619 未加载
评论 #26786168 未加载
jbverschoorabout 4 years ago
The example shouldn’t be compared to esleif, that’s not how switches work.<p>Also, because it throws you can just use if, without a block. Or use if at the end of the line if your language supports that.<p>Way cleaner (less indentation), and less error prone. Switch statements only exist because of the underlying assembly&#x2F;opcode.<p>It just as bad as goto, because it IS goto. The cases are goto-labels. It behaves like goto, and will simply generate the same JE&#x2F;JNE jumps
brundolfabout 4 years ago
It&#x27;s interesting, but I can&#x27;t decide if it&#x27;s an anti-pattern or not. You&#x27;re abusing a construct to achieve a slight improvement in brevity&#x2F;readability, with the downside of JS&#x27;s lack of block-scoping for case statements which means variables in one case can conflict with variables in other cases<p>All in all: I probably won&#x27;t be using it
crishojabout 4 years ago
While readable and aesthetically pleasing, I find myself wondering about the performance implications of switch(true) versus a multi-branched if-else. Does V8 (and PHP) treat each construct differently when it comes to optimizations? We&#x27;re not in C-land here, so jump tables are presumably not in play.
8128js8121about 4 years ago
``` switch (true) { case 1 + 1 === 2: &#x2F;&#x2F; This case evaluates to true so it will be executed default: &#x2F;&#x2F; This will not be executed } ```<p>This is wrong, Since there is no return or break default will also be executed.
darepublicabout 4 years ago
I prefer this pattern over long if else chains but I can never convince colleagues of this so I save this for code that I fully own
SergeAxabout 4 years ago
— What bad patterns of JavaScript programming do you know?<p>— Programming in JavaScript is a bad pattern itself.