Skip to content

Martin Belev

How to use pattern matching in JavaScript - an alternative?

JavaScript2 min read

JavaScript functional programming

We are going to quickly see what is pattern matching, see basic examples of it in Scala and make an analogy with one less known usage of JavaScript switch statement.

There is no native support for pattern matching in JavaScript. However, there is an open proposal which is great and it would be nice to have support and use it in the future if it gets approved and goes through all of the stages.

Note: this isn't a tutorial about Scala pattern matching and the given examples will be simple ones without going into details.

Let's get started!


Link to this heading
What is pattern matching?

It is a mechanism for checking/testing a value against a given pattern. The match should be exact. The logic for the first pattern that matches the value is executed. The patterns can vary and the functional programming languages support a variety of different usages.

Based on the Scala docs:

It is a more powerful version of the switch statement in Java and it can likewise be used in place of a series of if/else statements.

They are far more powerful than the usual switch statement. We will see how we can make an analogy with JavaScript switch statement though and use it in a way that gives us more control to write complicated expressions.

Link to this heading
Scala pattern matching examples

One of the simplest cases is match by value:

1def getMonthName(month: Int): String = month match {
2 case 1 => "January"
3 case 2 => "February"
4 // .etc
5 case _ => "Unknown"
6}
7getMonthName(13) // Unknown
8getMonthName(1) // January

JavaScript version:

1const getMonthName = (month) => {
2 switch (month) {
3 case 1:
4 return 'January';
5 case 2:
6 return 'February';
7 // .etc
8 default:
9 return 'Unknown';
10 }
11};
12
13getMonthName(13); // Unknown
14getMonthName(1); // January

We can have matching on type:

1abstract class Device
2case class Phone(model: String) extends Device {
3 def screenOff = "Turning screen off"
4}
5case class Computer(model: String) extends Device {
6 def screenSaverOn = "Turning screen saver on..."
7}
8
9def goIdle(device: Device) = device match {
10 case p: Phone => p.screenOff
11 case c: Computer => c.screenSaverOn
12}

There are a lot of other different usages of pattern matching that Scala supports but this is not the focus of this blog post. If you are interested in seeing them you can check out pattern matching and match expressions.

Link to this heading
JavaScript switch statement quick overview

From my experience in almost all of the places I have worked, switch is used in its traditional form as switch (someValue) and then case statements with simple numbers or strings.

Let's see an example from MDN docs:

1const value = 'Papayas';
2switch (value) {
3 case 'Oranges':
4 console.log('Oranges are $0.59 a pound.');
5 break;
6 case 'Mangoes':
7 case 'Papayas':
8 console.log('Mangoes and papayas are $2.79 a pound.');
9 // expected output: "Mangoes and papayas are $2.79 a pound."
10 break;
11 default:
12 console.log(`Sorry, we are out of ${value}.`);
13}

This is great but it feels like we are limited to simple values only. What if we want to add additional conditions or we want to use more complex data structures like lists, dictionaries, .etc?

Link to this heading
One less known usage of switch statement in JavaScript

If we try to formulate a question of what we want to do, it would be - what should we do if we want to write whatever expressions we want in the case statements and if one is true execute some logic?

By asking the question we have already answered it by if some of them is true. We can pass true as value for our switch statement and then the logic for the first case expression that evaluates to true will be executed.

Let's take a look at an example:

1const getCompactAmount = (amount) => {
2 switch (true) {
3 case amount / 1000000 >= 1:
4 return `${amount / 1000000}M`;
5 case amount / 1000 >= 1:
6 return `${amount / 1000}K`;
7 default:
8 return amount;
9 }
10};
11
12getCompactAmount(2000000); // 2M
13getCompactAmount(5000); // 5K
14getCompactAmount(123); // 123

We want to match our expressions to true which gives us the power to write whatever expressions we would like with whatever complicated conditions we need.

Link to this heading
Conclusion

This, of course, can be achieved by using if/else if/else statements and I guess it is a matter of preference what to use. I am not saying that this should be always used but it gives some nice opportunities and I think is a less known usage which I haven't seen much. As someone who isn't a big fan of switch statements and tried to avoid using them, I would say that after I have used switch (true) for a while I am more than happy with it. I find it much easier to read than multiple if/else if statements and less error-prone.


Thank you for reading this to the end 🙌 . If you enjoyed it and learned something new, support me by clicking the share button below to reach more people and/or give me a follow on Twitter where we can catch up. I am sharing some other tips, articles, and things I learn there.
If you didn't like the article or you have an idea for improvement, please reach out to me on Twitter and drop me a DM with feedback so I can improve and provide better content in the future 💪.

© 2021 by Martin Belev. All rights reserved.