Tejas Manohar

@tejasmanohar

Flip the Switch

Over the years, I’ve read (and heard) a lot of reasons why switch statements are harmful, dumb, and even smelly (lol). I don’t like to hate on a particular feature, and Douglas Crockford explains exactly why in the first chapter of his legendary book JavaScript: The Good Parts-

Most programming languages contain good parts and bad parts. I discovered that I could be a better programmer by using only the good parts and avoiding the bad parts.

The switch statement is a competent feature. Like most competent features, it has loads of problems with it- the requirement of using break after every statement within a case, procedural control flow, out-of-place syntax, handling of code blocks, and much much more! Unfortunately, solving these problems would require us to rewrite how it operates at the core and the spec would entirely change, which, for a language like JavaScript, would create massive backwards compatibility issues. Again, I’ll quote Crockford-

It is rarely possible for standards committees to remove imperfections from a language because doing so would cause the breakage of all of the bad programs that depend on those bad parts. They are usually powerless to do anything except heap more features on top of the existing pile of imperfections. And the new features do not always interact harmoniously, thus producing more bad parts.

So what do we do instead? We consider it a suboptimal feature because it’s simply inferior to other options available to JavaScript developers and move on. Today, we’ll examine one of these superior alternatives- the object literal. The Object literal approach to creating a switch-like control flow utilizes a hash table lookup and, obviously, uses Objects, the basis for the JavaScript language — we use them for everything!

Let’s start off by looking at this basic control flow that reports the price of a certain fruit using a switch statement.

function getPrice(fruit) {
var price;
switch (fruit) {
case 'orange':
price = 2.99;
break;
case 'apple':
price = 1.24;
break;
case 'cherry':
price = 3.55;
break;
default:
price = 1.11;
}
return 'My fruit costs ' + price;
}
console.log(get('apple')); // => My fruit costs 1.24
console.log(getPrice('apricot')); // => My fruit costs 1.10

Now, let’s rewrite this with a very simple Object literal.

function getPrice(fruit) {
var fruits = {
orange: 2.99,
apple: 1.24,
cherry: 3.55,
default: 1.11
};
return 'My fruit costs' + (fruits[fruit] || items['default']);
}

This is already a lot cleaner and shorter. We can simplify further by skipping on assignment and utilizing the || (OR) operator for defaults. Most of all, never forget a break again!

function getDrink(type) {
return 'My fruit costs ' + ({
orange: 2.99,
apple: 1.24,
cherry: 3.55
}[type] || 1.11);
}
// undefined || 1.11 === 1.11

By now, you should be able to tell that Object literals are superior to switch statements in crafting a cleaner control flow. However, we should also explore how they are actually more extensible-

function getPrice(fruit) {
var fruits = {
orange: function () {
return 2.99;
},
apple: function () {
return 1.24;
},
cherry: function () {
return 3.55;
},
default: function () {
return 1.11;
}
};
return (fruits[fruit] || fruits[‘default’])();
}

Sometimes, we may need to assign complex operations to a certain condition in our control flow, and in fact, we can define functions inline as keys of Object literals. Obviously, in the example above, a function is wholly unnecessary, but it serves as an adequate demonstration of the ability.

Use Object literals to develop natural, clean, and flexible control flows when programming JavaScript applications. Happy coding!

More by Tejas Manohar

Topics of interest

More Related Stories