DEV Community

Cover image for JavaScript Conditional Branching
Bello Osagie
Bello Osagie

Posted on • Updated on

JavaScript Conditional Branching


Conditions are boolean values , true or false. It is true if it meets the requirement, false otherwise. That is expressions (conditions) are evaluated to either true or false.

There are methods to check for a truthy condition:

  • If statement;
  • if..else statement;
  • else if statements;
  • switch statements;
  • ternary statements;

If statement

The if statement checks if a condition (...) is true. If true, the statements in a block scope get executed.

Syntax:

if (condition) {
    statement1;
    statement2;
         .
         .
    statementN;
}
Enter fullscreen mode Exit fullscreen mode

The condition must be true for the statements 1 to N to be executed.

Below is an example:

if (true) {
    console.log('statement will be executed'); 
// statement will be executed
}
Enter fullscreen mode Exit fullscreen mode

Truthy values include true, '...', and numbers except 0.

The code snippet above can be rewritten as shown below:

if (1) {
    console.log('statement will be executed'); 
// statement will be executed
}
Enter fullscreen mode Exit fullscreen mode

For a falsy condition, statements are not executed.

if (false) {
    console.log('statement will not be executed'); // no output
}
Enter fullscreen mode Exit fullscreen mode

Falsy values are false, 0, '', null, undefined, NaN.

The code snippet above can be rewritten as shown below:

if (0) {
    console.log('statement will be executed'); // no output
}
Enter fullscreen mode Exit fullscreen mode

else if statements

It is possible to have multiple false conditions and one truthy condition.

When there are multiple conditions to choose from, only the first correct truthy condition gets to execute the statement.

const num = 25;

if (num > 26) {
  console.log('Yes!');
} else if (num > 21) {
  console.log('I think so'); // I think so
} else if (num > 22) {
  console.log('I think so too');
} 
Enter fullscreen mode Exit fullscreen mode

Because a condition was already true (25 > 21), other truthy options get ignored (25 > 22).


image.png


else statement

The else statement is also called the default statement because it gets executed when other options (if and else if statements) are false.

const num = 25;

if (num > 26) {
  console.log('No!');
} else if (num < 21) {
  console.log("I don't think so");
} else if (num < 22) {
  console.log("I also don't think so too");
} else {
  console.log('Yes!'); // Yes
} 
Enter fullscreen mode Exit fullscreen mode

switch statements

The switch statement is an alternate method to if and if..else if statements.

Below is an alternative, but the easier way of writing if...else if statements:

const num = 25; 

switch (num) {
  case 26: 
    console.log('No!');
    break;
  case 21:
  case 22:
  case 23:
  case 24:
    console.log("I don't think so");
    break;
  default:
    console.log('Yes!'); // Yes!
}
Enter fullscreen mode Exit fullscreen mode

The break keyword breaks from the current case if it's false.


Ternary Conditional Operator

Ternary operator ? has three operands around it. It is the best alternative to the if...else statement.

Syntax:

condition ? true : false; 
// or
condition ? value1 : value2;
Enter fullscreen mode Exit fullscreen mode

Operands are:

  • condition,
  • true, and
  • false

See the example below:

const age = 28;

const checkAge = (age > 23) ? 'Yes!' : 'No!';
console.log(checkAge); // Yes!
Enter fullscreen mode Exit fullscreen mode

The ternary conditional operator can also replace the if..else if statements.

const age = 28;

const checkAge = (age < 10) ? 'Not at all!' : 
(age < 10) ? "I don't think so!":
(age > 26) ? "Yes!":
'else the above options are false';

console.log(checkAge); // Yes!
Enter fullscreen mode Exit fullscreen mode

Conditions with single statements

For conditions with single statements, the curly braces {} can be omitted.

const age = 20;

if (age < 5) {
  console.log('No!');
} else {
  console.log('Yes!'); // Yes!
}
Enter fullscreen mode Exit fullscreen mode

Below is the same code snippet above but shorter:

const age = 20;

if (age < 5) console.log('No!');
else console.log('Yes!'); // Yes!
Enter fullscreen mode Exit fullscreen mode

For better code readability, use cure braces always (optional).

Happy Coding!!!


Buy me a Coffee


TechStack Media | Bluehost

  • Get a website with a free domain name for 1st year and a free SSL certificate.
  • 1-click WordPress install and 24/7 support.
  • Starting at $3.95/month.
  • 30-Day Money-Back Guarantee.

Top comments (14)

Collapse
 
robertseidler profile image
RobertSeidler • Edited

I really like the ternary operator in theory. Beeing able to have branching in an expression is lovely, but I hate how hard it is to read in JS (exponentially worse for nested branches).
I think python chose a way better syntax for expression branching:
Instead of:

ageGroup = (age >= 18) ? 'Adult' : "Child"
Enter fullscreen mode Exit fullscreen mode

You got:

ageGroup = 'Adult' if age >= 18 else 'Child'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bello profile image
Bello Osagie
a = 5
b = 10
check_condition = True if a < b else False 
print(check_condition) # True
Enter fullscreen mode Exit fullscreen mode

That may be true because some people will disagree with you. But generally, python has a better syntax. That is why Python is used for complex code structure in AI, machine Learning, data science, etc.

If you already know JavaScript on the browser or web, I recommend trying out Brython...

Collapse
 
robertseidler profile image
RobertSeidler

I'll give Brython a go, never heard of it :D

But JS has it's pros, too. In python I do miss having functions as first class objects (although that might help python, still. Making it more clear). And everything async feels slugish in python compared to js.

I enjoy switching back and forth every now and again.

Thread Thread
 
bello profile image
Bello Osagie

That's because you used Python... It happens to everyone at some point...

Collapse
 
peerreynders profile image
peerreynders
Collapse
 
robertseidler profile image
RobertSeidler

I do feel more and more drawn towards a more functional / declarative style of programming. It makes it (at least for me) more intuitive (both when reading and writing), than either imperative or object oriented.

Thread Thread
 
peerreynders profile image
peerreynders

I'm not sure that Python is the right "medium" for a functional/declarative style.

Collapse
 
rxliuli profile image
rxliuli

In more complex situations, it would be more appropriate to use object-oriented polymorphism (class support contains state rather than just functions)

Collapse
 
peerreynders profile image
peerreynders

ECMAScript Pattern Matching (if it ever lands) can clean up complex expression based data transformations considerably.

Collapse
 
robertseidler profile image
RobertSeidler

pattern matching would be awesome. I wanna have it everywhere

Thread Thread
 
peerreynders profile image
peerreynders • Edited

Sometimes the stars align and you get to "fake it" with a Bitwise OR (|):

const KIND = Object.freeze({
  Equilateral: 'equilateral',
  Isosceles: 'isosceles',
  Scalene: 'scalene',
});

const LEGS = Object.freeze({
  NotEqual: 0x0,
  LargerEqual: 0x1,
  SmallerEqual: 0x2,
});

const keepPositive = (side) => side > 0;
const numericAsc = (a, b) => a - b;

function kind(sides) {
  const triangle = sides.filter(keepPositive);
  if (triangle.length != 3)
    throw new Error(`Not all sides are positive: ${sides}`);

  triangle.sort(numericAsc);
  const [a, b, c] = triangle;
  if (a + b <= c) throw new Error(`Triangle inequality violated: ${sides}`);

  // "faking" pattern matching
  switch (
    (a === b ? LEGS.SmallerEqual : LEGS.NotEqual) |
    (b === c ? LEGS.LargerEqual : LEGS.NotEqual)
  ) {
    case LEGS.SmallerEqual | LEGS.LargerEqual:
      return KIND.Equilateral;
    case LEGS.SmallerEqual:
    case LEGS.LargerEqual:
      return KIND.Isosceles;
    default:
      return KIND.Scalene;
  }
}

console.assert(kind([2, 2, 2]) === 'equilateral', 'Equilateral failed');
console.assert(kind([3, 4, 4]) === 'isosceles', 'Isosceles (first side) failed');
console.assert(kind([4, 3, 4]) === 'isosceles', 'Isosceles (second side) failed');
console.assert(kind([4, 4, 3]) === 'isosceles', 'Isosceles (third side) failed');
console.assert(kind([3, 4, 5]) === 'scalene', 'Scalene failed');
console.assert(kind([0.4, 0.6, 0.3]) === 'scalene', 'Short sides scale failed');
console.assert(throws(() => kind([0, 0, 0])), 'No size failed to throw');
console.assert(throws(() => kind([3, 4, -5])), 'Negative side failed to throw');
console.assert(throws(() => kind([7, 3, 2])), 'Triangle inequality violation failed to throw');
console.log('done.');

function throws(fn) {
  let caught = false;

  try {
    fn();
  } catch (_error) {
    caught = true;
  }
  return caught;
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
robertseidler profile image
RobertSeidler

clever, I had to stare at it for a few minutes to go through all the possibilities.

That's where the real beauty of a neatly syntaxed pattern matching expression could do a great deal to make it super obvious, what one wants to express with their code.

Thread Thread
 
peerreynders profile image
peerreynders

I had to stare at it for a few minutes to go through all the possibilities.

That's possibly because of lack of familiarity.

The Rust equivalent doesn't look that different to me:

fn categorize(mut sides: [T; 3]) -> Option<Category> {
    sides.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
    let [a, b, c] = sides;
    let is_triangle = a + b > c;
    if is_triangle {
        Some(match (a.eq(&b), b.eq(&c)) {
            (true, true) => Equilateral,
            (true, _) | (_, true) => Isoceles,
            _ => Scalene,
        })
    } else {
        None
    }
}
Enter fullscreen mode Exit fullscreen mode

in particular

match (a.eq(&b), b.eq(&c)) {
    (true, true) => Equilateral,
    (true, _) | (_, true) => Isoceles,
     _ => Scalene,
}
Enter fullscreen mode Exit fullscreen mode

In Erlang (and Elixir is similar) something like (again, assuming that the sides are sorted by length so that equal sides will always be adjacent)

case Sides of
  {A, A, A} -> "equilateral";
  {A, A, C} -> "isosceles"; 
  {A, B, B} -> "isosceles";
  _ -> "scalene"   
end.

Enter fullscreen mode Exit fullscreen mode

or

case Sides of
  {A, B, C} when A == B andalso B == C -> "equilateral";
  {A, B, C} when A == B orelse B == C -> "isosceles"; 
  _  -> "scalene"
end.

Enter fullscreen mode Exit fullscreen mode

ReScript (aka ReasonML; JavaScript flavored OCaml)

let kind = switch (a === b, b === c) {
| (true, true) => "equilateral"
| (true, _) | (_ , true) => "isosceles"
| _  => "scalene"
}
Enter fullscreen mode Exit fullscreen mode

etc.

Thread Thread
 
robertseidler profile image
RobertSeidler • Edited

That's possibly because of lack of familiarity.

very likely.

And nice overview, of how different languages handle the same problem