How to check for null/undefined in JavaScript

0

This post is also available in different formats so you can read on the go or share it around!

null and undefined are used in JavaScript to represent the absence of a value, and they can take some care when dealing with them. There are a couple of ways we can approach the problem, so let’s have a look at the oldest and most used. Then we’ll have a look at a newer feature that makes object access much easier.

Explicit checks

The tried and true way to check for null/undefined is by comparison.

const checkPantry = (juice) => {
  if (juice) {
    console.log(`we have ${juice} juice`);
  }
}

let juice;
checkPantry(juice) // nothing will be printed

juice = 'pineapple'
checkPantry(juice) // 'we have pineapple juice'

The if statement accepts an expression, in JS, null and undefined will be false so we can easily check to see if the value exists.

If you are treating null and undefined as different things in your program, you could explicitly check the value like this:

const checkPantry = (juice) => {
  if (juice === null) {
    console.log('we ran out of juice');
  } else if (juice === undefined) {
    console.log('not sure if there is any juice')
  } else {
    console.log(`we have ${juice} juice`);
  }
}

let juice;
checkPantry(juice) // 'not sure if there is any juice'

juice = 'pineapple'
checkPantry(juice) // 'we have pineapple juice'

juice = null
checkPantry(juice) // 'we ran out of juice'

Generally, null and undefined can be treated similarly for values, so it’s not necessary to check this explicitly. Let’s have a look at another useful feature which can help in more complicated cases.

Optional chaining

When dealing with objects, there are times when you want a property but don’t know if it exists. In the past, this could be annoying when looking deeply into an object but optional chaining was added and has full support across all major browsers, and has done for some time.

Let’s have a look at some different examples.

Properties

Accessing a property of an object will be undefined it doesn’t exist, but if you access a property on undefined, you’ll receive a TypeError — optional chaining means we can use the ?. to attempt to access a nested property and return undefined if ID doesn’t exist.

const shelf = {
  top: {
    plate: 3
  },
  bottom: {
    can: 8,
      chest: {
        letter: 2
      }
    }
  }
}

shelf.middle // undefined
shelf.top.chest.letters // Throws a TypeError exception
shelf.top?.chest?.letters // undefined

This is much nicer than the alternative in the past, which involved defensive checks to figure out if a nested value could be accessed.

Expressions

Another useful case for optional chaining comes from the [] accessor syntax, this can be useful with objects and arrays.

const ids = [1,2,3]

ids[1] // 2
ids?.[1] // 2

let names;

names[0] // Throws a TypeError exception
names?.[0] // undefined

This makes it much easier to deal with dynamic values without having to check the values before attempting to access a property.

Functions

Finally, optional chaining works with functions too. Especially useful in JavaScript, as you can treat functions like values. This cleans up additional checks like with callbacks like this:

function makeCoffee(onDone) {
  console.log('grinding')
  console.log('prepping')
  console.log('brewing')

  if (onDone) {
    onDone()
  }
}

Now becomes this:

function makeCoffee(onDone) {
  console.log('grinding')
  console.log('prepping')
  console.log('brewing')

  onDone?.()
}

Optional chaining is useful syntax sugar which saves some typing and often makes logic easier to read through and understand. You’re much less likely to run into a TypeError using optional chaining.

Resources

Seth Corker

A Fullstack Software Engineer working with React and Django. My main focus is JavaScript specialising in frontend UI with React. I like to explore different frameworks and technologies in my spare time. Learning languages (programming and real life) is a blast.