DEV Community

Cover image for The Ternary Operator
NRF
NRF

Posted on • Updated on • Originally published at blog.bracketsinstitute.com

The Ternary Operator

This article is part of the first installment of a series I'm calling JavaScript You Must Know. The aim of this series is to go over various fundamentals of the JavaScript language that a developer must know/understand before moving forward with any of the modern JavaScript frameworks like React, Angular, and Vue. Learning these fundamentals in parallel with the frameworks would also be acceptable.

This first installment of the series focuses on syntax-related topics and is called JavaScript You Must Know -- Essential Syntax.


The ternary operator is simply a shorthand for an if...else statement. It is used very liberally by JavaScript developers (and developers of other languages that have this operator). These days it is especially common to see the ternary operator being used in React code.

Syntax

The ternary operator is the only operator in JavaScript that takes three operands. Its syntax may take some getting used to but it is actually quite straightforward. Let's take a look. Please note that the parentheses and the angle brackets are not part of the syntax; I'm just using them for readability.

(condition) ? <expression A> : <expression B>

  • condition: an expression that evaluates to a truthy or a falsey value
  • expression A: this expression is evaluated/executed if the condition is true
  • expression B: this expression is evaluated/executed if the condition is false

The equivalent if...else statement for the example above would be:

if (condition) {
  <expression A>
} else {
  <expression B>
}
Enter fullscreen mode Exit fullscreen mode

Let's consider a more realistic(-ish) example. Assume we need a function that takes the current temperature value as its argument and returns a string saying if it is hot outside or not. Using an if...else statement, one might code the function like this:

function tellMeIfItsHotOutside(outsideTempInCelsius) {
  if (outsideTempInCelsius > 30) {
    return "It is kinda hot";
  } else {
    return "Na, not really hot";
  }
}

console.log(tellMeIfItsHotOutside(25)); // output: "Na, not really hot"
console.log(tellMeIfItsHotOutside(31)); // output: "It is kinda hot"
Enter fullscreen mode Exit fullscreen mode

Now, if we use the ternary operator instead of the if...else statement inside the tellMeIfItsHotOutside() function, it would look like this:

function tellMeIfItsHotOutside(outsideTempInCelsius) {
  return (outsideTempInCelsius > 30) ? "It is kinda hot" : "Not really hot";
}

console.log(tellMeIfItsHotOutside(25)); // output: "Na, not really hot"
console.log(tellMeIfItsHotOutside(31)); // output: "It is kinda hot"
Enter fullscreen mode Exit fullscreen mode

Looking at the examples above, I'd say that both are equally readable but the ternary operator is much more concise.

Nested Ternary Operator

The ternary operator can also be nested. For example, if you have an if...else statement like this:

if (firstCondition) {
  <expression A>
} else if (secondCondition) {
  <expression B>
} else {
  <expression C>
}
Enter fullscreen mode Exit fullscreen mode

You can replace it using the ternary operator:

(firstCondition) ? <expression A> :
  ((secondCondition) ? <expression B> : <expression C>);
Enter fullscreen mode Exit fullscreen mode

We've basically just replaced <expression B> with another conditional statement that uses the ternary operator. The same can be done with <expression A> as well. Remember, <expression A> and <expression B> (considering the first ternary example) can be any valid JavaScript expressions. This includes arithmetic and logical expressions, function calls, and more ternary expressions.

Let's apply all of this to our outside temperature example and say that our tellMeIfItsHotOutside() function is a tad more specific and follows the following logic:

  • If the outside temperature is more than 40 degrees, return "Very hot; stay in"
  • If the outside temperature is between 30 and 40 degrees, return "Yeah, it is hot"
  • If the outside temperature is between 25 and 30 degrees, return "Kinda hot, but not too much"
  • If the outside temperature is 25 degrees or less, return "It's actually really nice out"

First, let's do the if...else version.

function tellMeIfItsHotOutside(outsideTempInCelsius) {
  if (outsideTempInCelsius > 40) {
    return "Very hot; stay in";
  } else if (outsideTempInCelsius > 30) {
    return "Yeah, it is hot";
  } else if (outsideTempInCelsius > 25) {
    return "Kinda hot, but not too much";
  } else {
    return "It's actually really nice out";
  }
}

console.log(tellMeIfItsHotOutside(41)); // output: Very hot, stay in
console.log(tellMeIfItsHotOutside(32)); // output: Yeah, it is hot
console.log(tellMeIfItsHotOutside(26)); // output: Kinda hot, but not too much
console.log(tellMeIfItsHotOutside(22)); // output: It's actually really nice out
Enter fullscreen mode Exit fullscreen mode

Now let's see what the same function would look like if we had used the ternary operator.

function tellMeIfItsHotOutside(outsideTempInCelsius) {
  return (
    (outsideTempInCelsius > 40) ? "Very hot; stay in" :
      (outsideTempInCelsius > 30) ? "Yeah, it is hot" :
        (outsideTempInCelsius > 25) ? "Kinda hot, but not too much" : "It's actually really nice out"
  );
}

console.log(tellMeIfItsHotOutside(41)); // output: Very hot, stay in
console.log(tellMeIfItsHotOutside(32)); // output: Yeah, it is hot
console.log(tellMeIfItsHotOutside(26)); // output: Kinda hot, but not too much
console.log(tellMeIfItsHotOutside(22)); // output: It's actually really nice out
Enter fullscreen mode Exit fullscreen mode

If you're not already used to the syntax of the ternary operator then I'd highly recommend doing this example on your own so the syntax sinks in nicely. Note that I've used indents and line breaks to make the syntax more readable. In my opinion the ternary version is much more readable in this case. Some of you may find the if...else version more readable. The important thing is to have code-readability as a priority. Always take some time to think which version will be easier to read and follow. Because that is the version that will be easier to debug, refactor, expand, and all that jazz.


👉🏻 Subscribe to my newsletter: click here

👉🏻 Follow me on twitter: click here


Discussion (4)

Collapse
teamradhq profile image
teamradhq

Conditional operator is a short-hand for a ternary statement with one input and two outputs:

function foo(bar) {
  if (bar) {
    return 'baz';
  } else {
    return 'blitz';
  }  
}

Enter fullscreen mode Exit fullscreen mode

Sure, it's convenient for simple expressions like this to shorten them:

const foo = bar => bar ? 'baz' : 'blitz';
Enter fullscreen mode Exit fullscreen mode

At the same time though, we should consider that the ternary statement isn't necessary here:

function foo(bar) {
  if (bar) {
    return 'baz';
  }

  return 'blitz';
}
Enter fullscreen mode Exit fullscreen mode

I'd caution against using the conditional operator too often, and would never recommend nesting ternary statements in this manner. If you have to nest conditional operators, you're not writing a ternary statement.

Consider this an anti-pattern because this is not a ternary statement:

function tellMeIfItsHotOutside(outsideTempInCelsius) {
  return (
    (outsideTempInCelsius > 40) ? "Very hot; stay in" :
      (outsideTempInCelsius > 30) ? "Yeah, it is hot" :
        (outsideTempInCelsius > 25) ? "Kinda hot, but not too much" 
                : "It's actually really nice out"
  );
}
Enter fullscreen mode Exit fullscreen mode

^ This is clever code and its readability is entirely subjective. You can understand it, and I can understand it. A lot of people couldn't. And even with my experience, it took me a while to understand what was happening. For a while, I even thought that the last condition was a bug that would never be called.

In this case, a ternary statement isn't necessary or appropriate, because there is more than one input and more than two outputs.

Our truth table is more like this:

case temp result
0 > 40 "Very hot; stay in"
1 > 30 "Yeah, it is hot"
2 > 25 "Kinda hot, but not too much"
3 < 25 "It's actually really nice out"

That's one input and four outputs. Not really a ternary statement...

I'd suggest this would be more appropriate:

export function tellMeIfItsHotOutside(temp) {
  if (temp > 40) {
    return "Very hot; stay in";
  }

  if (temp > 30) {
    return "Yeah, it is hot";
  }

  if (temp > 25) {
    return "Kinda hot, but not too much";
  }

  return "It's actually really nice out";
}
Enter fullscreen mode Exit fullscreen mode

It's not clever, it's simple and stupid, and other developers will be able to comprehend it immediately. Given this is a self contained function, there's no ned to be concise or clever. We just need to be clear.

I've also renamed the variable temp because if we really need more information, such as unit of measurement, we can put it in documentation:

/**
 * @param   {number}  temp  The temperature in celcius
 * @return  {string}
 */
export function tellMeIfItsHotOutside(temp) {
  // ...
}
Enter fullscreen mode Exit fullscreen mode

I'd only recommend conditional operators where conciseness is beneficial to readability:

// higher order function
array.filter(n => condition ? 'yes' : 'no');

// template literal
const format = ({ correct }) => `Answer: ${correct ? 'correct' : 'incorrect' }`;

// component template
function SomeComponent(props: ComponentProps) {
  // ...

  return (props.isLoaded ? <PostContent props={...props}> : <Loading>);
}
Enter fullscreen mode Exit fullscreen mode

Use a ternary if your expression is simple and its logic takes the form of:

case result
true 1
false 0
Collapse
nrf profile image
NRF Author

Appreciate your detailed comment. I do agree with most of it. In fact, the only reason I included this operator in the series was because of its use in conditional rendering in React.

I did try to emphasize that its use was subjective. I've worked with programmers on both side of the fence. Some don't use it unless they have to, others don't really mind.

The nested example was necessary, in my opinion, just to show that it can be nested.

Collapse
damienpirsy profile image
Matteo Vignoli

Couldn't say it better. Also, ternary operators, like one-liners, sometimes are used just to show off some supposed programming skills - failing to understand that writing code that can be easily read is a way more appreciated and useful programming skill than codegolfing or saving a few spaces here and there.

Collapse
jonrandy profile image
Jon Randy • Edited on

Its name is actually the conditional operator. It just so happens that it is a ternary operator (an operator that has 3 operands, just has a binary operator has 2, and a unary operator has 1). As you say, JavaScript only has one operator like this, so it is sometimes referred to as 'the' ternary operator