loading...
Cover image for How to use pattern matching in JavaScript - an alternative?

How to use pattern matching in JavaScript - an alternative?

martinbelev profile image Martin Belev Originally published at belev.dev ・4 min read

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!


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.

Scala pattern matching examples

One of the simplest cases is match by value:

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

JavaScript version:

const getMonthName = (month) => {
  switch (month) {
    case 1:
      return 'January';
    case 2:
      return 'February';
    // .etc
    default:
      return 'Unknown';
  }
};

getMonthName(13); // Unknown
getMonthName(1); // January

We can have matching on type:

abstract class Device
case class Phone(model: String) extends Device {
  def screenOff = "Turning screen off"
}
case class Computer(model: String) extends Device {
  def screenSaverOn = "Turning screen saver on..."
}

def goIdle(device: Device) = device match {
  case p: Phone => p.screenOff
  case c: Computer => c.screenSaverOn
}

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.

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:

const value = 'Papayas';
switch (value) {
  case 'Oranges':
    console.log('Oranges are $0.59 a pound.');
    break;
  case 'Mangoes':
  case 'Papayas':
    console.log('Mangoes and papayas are $2.79 a pound.');
    // expected output: "Mangoes and papayas are $2.79 a pound."
    break;
  default:
    console.log(`Sorry, we are out of ${value}.`);
}

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?

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:

const getCompactAmount = (amount) => {
  switch (true) {
    case amount / 1000000 >= 1:
      return `${amount / 1000000}M`;
    case amount / 1000 >= 1:
      return `${amount / 1000}K`;
    default:
      return amount;
  }
};

getCompactAmount(2000000); // 2M
getCompactAmount(5000); // 5K
getCompactAmount(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.

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. I hope you enjoyed it and learned something new. If so, please follow me on Twitter where I will share other tips, new articles, and things I learn. If you would like to learn more, have a chat about software development, or give me some feedback, don't be shy and drop me a DM.

Discussion

pic
Editor guide