Maintain Readability for Conditional Assignments with JavaScript IIFEs

Alex Reardon
InstructorAlex Reardon
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 5 years ago

This lesson will show you how you can use Immediately Invoked Function Expressions (IIFE's) to make conditional assignments more readable and robust

Instructor: [00:00] Here, we have a conditional assignment. We are conditionally assigning the value of the variable greeting based on another variable isJoiningRoom.

[00:09] If isJoiningRoom is truthy, then greeting will be set to Hello. Otherwise, it will be set to Goodbye. This conditional assignment is achieved using a ternary statement.

[00:24] Here, we have a more complex conditional assignment. Now the variable greeting is based on a number of other variables.

[00:33] If isJoiningRoom is set to true, then greeting will be set to Welcome. If isLeavingRoom is true, then greeting will be set to Goodbye. If isReEnteringRoom is set to true, greeting will be set to Welcome back. If none of these are true, greeting will be set to Hi.

[00:51] This conditional assignment uses nested ternary statements. Nested ternary statements are generally considered to be hard to maintain as their structure can be difficult to follow.

[01:06] In this example, we are achieving the same complex conditional assignment using if-else statements. We firstly declare the variable greeting with no assignment. At this point, its value will be undefined. We then walk through the if statements to assign a value to the greeting variable.

[01:28] Using if-else statements for complex conditional assignments, it's much clear to read than the nested ternary statement. However in order to use this approach, we need to split the declaration of the variable greeting from its assignment, which is done later.

[01:47] The variable greeting has its type changed from undefined to a string after the if-else statements. Due to the split between the declaration and assignment, we can no longer able to use the const keyword. Rather, we now need to use the let keyword.

[02:11] Another way of achieving conditional assignments is to use an immediately-invoked function expression, or IIFE. An IIFE is a function that will be immediately executed in place. When we declare our variable greeting, we can assign its value to the result of the IIFE.

[02:32] Here, we have the same complex conditional assignment we had previously performed using an IIFE. We were able to maintain the readability of using if-else statements for conditional assignment without needing to split the declaration of the variable greeting from its assignment.

[02:50] Because there is no longer a split between the declaration and assignment of the variable greeting, we are able to use the const keyword for the greeting variable.

mister. jones
mister. jones
~ 6 years ago

Very cool. I too often reach for the nested ternary, because I like that it's an expression, despite knowing that it can be hard to reason about. The IIFE definitely works as a good replacement.

However, I also find myself using nested ternaries because I don't like all the "noise" that comes with if-else blocks. Looking at your example, I thought about this for a bit, and wondered, since we're simply checking a conditional and returning a value, maybe something like this inside the IIFE could work as well:

const greeting = (() => {
  const roomStatuses = [
    [isJoiningRoom, 'Welcome'],
    [isLeavingRoom, 'Goodbye'],
    [isEnteringRoom, 'Welcome back'],
    [true, 'Hi'],
  ]
  const roomStatus = roomStatuses.findIndex((element) => element[0])
  return roomStatuses[roomStatus][1]
})()

The logic getting the roomStatus value takes a second to understand versus reading through the if-else block, but I think the readability provided by the roomStatuses array could make it a worthwhile compromise.

Or, if the room status were being tracked as a string, instead of one of several Booleans, we could simplify it a bit with an object literal:

let roomStatus = 'isEnteringRoom'

// See: Replacing switch statements with Object literals | Todd Motto
//   https://toddmotto.com/deprecating-the-switch-statement-for-object-literals/
const greetingFromObject = (() => {
  const roomStatuses = {
    isJoiningRoom: 'Welcome',
    isLeavingRoom: 'Goodbye',
    isEnteringRoom: 'Welcome back',
    default: 'Hi',
  }
  return roomStatuses[roomStatus] || roomStatuses['default']
})()

Here's a jsfiddle of these two implementations in action: Conditional Assignments

Thank you for the inspiration! :)

Bijoy Thomas
Bijoy Thomas
~ 6 years ago

You could convert the booleans into strings and use them to index into a lookup like you have above (helper functions from ramda)

// booleans
const
isJoiningRoom = false,
isLeavingRoom = true,
isEnteringRoom = false

const greeting = compose(
  flip(prop)({isJoiningRoom: 'Welcome', isLeavingRoom: 'Goodbye', isEnteringRoom: 'Welcome back', 
    default: 'Hi', }),
  propOr('default', 'true'),
  invertObj
)({isJoiningRoom, isLeavingRoom, isEnteringRoom}) // turn the variables into keys which are strings
Markdown supported.
Become a member to join the discussionEnroll Today