Skip to content Skip to footer

Unwrapping the Double Question Mark in JavaScript: The Nullish Coalescing Operator

Ah, JavaScript, the language that keeps on giving. Just when you think you’ve got a handle on it, it pulls a new trick from its sleeve. Today, we’re diving deep into one of those newer tricks: the double question mark, also known as the Nullish Coalescing Operator. It’s a nifty little feature that’s been making waves since its introduction in ES2020, and for good reason.

What’s the Deal with ???

The double question mark ?? is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined. Otherwise, it returns the left-hand side operand. This may sound a bit like the good old logical OR (||), but there’s a subtle, yet powerful difference.

Consider this: the logical OR operator will return the right-hand side value if the left-hand side is any falsy value (like 0, '', false, null, or undefined). The Nullish Coalescing Operator, however, only cares about null or undefined. This makes it a more precise tool when you want to provide default values.

Let’s see it in action:

const userAge = 0;
const defaultAge = 18;

// Using logical OR
const ageWithOR = userAge || defaultAge; // 18, because 0 is falsy

// Using Nullish Coalescing Operator
const ageWithNullish = userAge ?? defaultAge; // 0, because userAge is not null or undefined

In this example, ageWithOR gives us 18, which is not what we want if we’re trying to respect a user’s age input of 0. On the flip side, ageWithNullish correctly gives us 0, because it only falls back to the default value if the left-hand side is null or undefined.

Practical Applications of ??

The Nullish Coalescing Operator shines in scenarios where default values are needed, but you also need to respect certain falsy values like 0 or an empty string. Let’s explore some practical code snippets across different JavaScript frameworks.

Vanilla JavaScript: Setting Defaults

In plain old JavaScript, you might use ?? to set default values for function parameters or variables that might be null or undefined.

function greet(name) {
  const userName = name ?? 'Stranger';
  console.log(`Hello, ${userName}!`);
}

greet(null); // Hello, Stranger!
greet('Alice'); // Hello, Alice!

React: Default Props and State

In a React component, the Nullish Coalescing Operator can be used to provide default values for props or state that might not be provided.

import React, { useState } from 'react';

const UserProfile = ({ age }) => {
  const [userAge] = useState(age ?? 18);

  return <p>Your age is {userAge}.</p>;
};

// In this case, if the age prop is not provided, it defaults to 18

Vue.js: Computed Properties and Data

In Vue.js, you can use ?? within computed properties or data functions to handle null or undefined values gracefully.

export default {
  data() {
    return {
      userAge: null,
    };
  },
  computed: {
    age() {
      return this.userAge ?? 18;
    },
  },
};

Angular: Class Properties and Functions

For Angular, you might find the Nullish Coalescing Operator useful when dealing with class properties or functions that could potentially be null or undefined.

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-user',
  template: `<p>Your age is {{ age }}.</p>`,
})
export class UserComponent {
  @Input() age: number | null | undefined;

  get userAge(): number {
    return this.age ?? 18;
  }
}

Node.js: Environment Variables

In a Node.js environment, ?? can be particularly handy when dealing with environment variables that may not be set.

const port = process.env.PORT ?? 3000;
console.log(`Server running on port ${port}`);

In this snippet, if process.env.PORT is not defined, the server defaults to port 3000.

Embracing the Nullish Coalescing Operator

Now that we’ve seen ?? in action across various JavaScript environments, it’s clear that this operator is more than just syntactic sugar. It provides a level of precision in our code that allows us to handle null and undefined values without unintentionally capturing other falsy values.

Edge Cases and Gotchas

While the Nullish Coalescing Operator ?? is a powerful addition to JavaScript, it’s not without its quirks. Understanding its behavior in edge cases is crucial to avoid unexpected bugs.

Interaction with Other Operators

One thing to keep in mind is how ?? interacts with other operators, especially || and &&. Due to operator precedence, mixing these without parentheses can lead to confusion:

const foo = null ?? 'default';
const bar = false || 'fallback';
const baz = foo || bar; // You might expect this to be 'default', but it's 'fallback'

const correctBaz = (foo ?? 'default') || bar; // This will correctly evaluate to 'default'

Always use parentheses to clarify the order of operations when mixing ?? with other logical operators.

Nullish Assignment Operator

Building on the concept of the Nullish Coalescing Operator is the Nullish Assignment Operator ??=. This operator assigns a value to a variable only if that variable is currently null or undefined.

let userName;

userName ??= 'Stranger';
console.log(userName); // 'Stranger'

userName ??= 'Another Name';
console.log(userName); // 'Stranger', since userName is already assigned

This operator is particularly useful for initializing variables without overwriting existing values.

TypeScript and Flow

If you’re using TypeScript or Flow, you’ll be pleased to know that both type checkers support the Nullish Coalescing Operator. This allows for even more robust type checking when dealing with nullable types:

function processInput(input: string | null | undefined) {
  const processedInput = input ?? 'No input provided';
  // processedInput is guaranteed to be a string here
}

Polyfills and Transpilation

For older environments that don’t support ES2020, you’ll need to use a polyfill or transpile your code. Tools like Babel offer plugins such as @babel/plugin-proposal-nullish-coalescing-operator, which allow you to use ?? and have it transpiled into compatible JavaScript for older browsers.

Performance Considerations

It’s worth noting that the Nullish Coalescing Operator can also have performance benefits. Since it only checks for null or undefined, it can be faster than a series of if statements or ternary operators checking for multiple falsy values.

Real-World Use Cases

Let’s look at some real-world scenarios where the Nullish Coalescing Operator can simplify code and make it more readable.

Configuration Objects

When dealing with configuration objects where optional values might be omitted, ?? can provide sensible defaults:

const config = {
  timeout: 0, // Intentionally set to 0
  // ...
};

const timeoutDuration = config.timeout ?? 5000;
console.log(`Timeout is set to ${timeoutDuration} milliseconds.`);

API Responses

When parsing API responses, you often encounter null or undefined values. The Nullish Coalescing Operator helps you set defaults while parsing:

fetch('/api/user')
  .then((response) => response.json())
  .then((user) => {
    const name = user.name ?? 'Anonymous';
    console.log(`Welcome, ${name}!`);
  });

Component Libraries

If you’re building a component library, ?? can help you provide default values for props without masking other falsy values that might be valid:

const Button = ({ disabled = false, label }) => {
  const buttonText = label ?? 'Click me!';
  return (
    <button disabled={disabled}>
      {buttonText}
    </button>
  );
};

Conclusion

The Nullish Coalescing Operator ?? is more than just a convenience—it’s a testament to the evolving nature of JavaScript. It provides a more explicit and intentional way of dealing with null and undefined values, helping developers write cleaner, more predictable code.

By understanding and leveraging ??, you can avoid common pitfalls associated with falsy values and bring a new level of clarity to your codebases. Whether you’re working on a personal project, a large enterprise application, or contributing to open-source, the Nullish Coalescing Operator is a tool well worth adding to your JavaScript toolkit.