javascript 26 lines · 5 steps

Optional chaining and nullish coalescing in JS

How ?. and ?? let you safely reach into nested objects and supply fallbacks without falsy bugs.

Explained by highlit
1function getCityName(user) {
2 return user?.address?.city ?? "Unknown city";
3}
4 
5function getFirstHobby(user) {
6 return user?.profile?.hobbies?.[0] ?? "No hobbies listed";
7}
8 
9function invokeFormatter(user) {
10 return user?.settings?.formatName?.() ?? "default formatter";
11}
12 
13function resolveConfig(options) {
14 const timeout = options?.timeout ?? 3000;
15 const retries = options?.retries ?? 0;
16 const headers = options?.headers ?? {};
17 return { timeout, retries, headers };
18}
19 
20function deepValue(obj, fallback) {
21 // ?. short-circuits to undefined the moment a link is null/undefined,
22 // ?? only falls back on null or undefined (not 0, '', or false).
23 const count = obj?.stats?.count ?? fallback;
24 const isActive = obj?.flags?.active ?? false;
25 return { count, isActive };
26}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Optional chaining short-circuits to undefined the instant any link in the path is null or undefined, avoiding 'cannot read property of undefined' errors.
  2. 2Nullish coalescing only falls back on null or undefined, so legitimate values like 0, '', and false survive untouched.
  3. 3Combining ?. and ?? gives concise, safe access to deep structures with explicit defaults at the call site.

Related explainers

javascript
const ROLE_PERMISSIONS = {
  admin: ['users:read', 'users:write', 'billing:read', 'billing:write'],
  manager: ['users:read', 'billing:read'],
  member: ['users:read'],

Role-based permissions middleware in Express

authorization middleware rbac
Intermediate 9 steps
javascript
function attachThousandSeparators(input, { locale = 'en-US' } = {}) {
  const formatter = new Intl.NumberFormat(locale);
  const groupSep = formatter.format(11111).replace(/\d/g, '')[0] || ',';
  const decimalSep = formatter.format(1.1).replace(/\d/g, '')[0] || '.';

Live thousand separators without losing the caret

dom intl caret-preservation
Advanced 8 steps
javascript
import { useReducer, useEffect } from "react";
 
const initialState = { status: "idle", data: null, error: null };
 

Building a data-fetching hook in React

custom-hooks usereducer data-fetching
Intermediate 9 steps
javascript
const express = require('express');
const app = express();
 
app.get('/health', (req, res) => res.json({ status: 'ok' }));

Graceful shutdown in an Express server

graceful-shutdown signal-handling connection-tracking
Advanced 9 steps
javascript
import { useState, useEffect, useCallback } from 'react';
 
function getColumnCount(width) {
  if (width < 640) return 1;

A responsive column hook in React

custom-hooks debouncing responsive-design
Intermediate 7 steps
javascript
function initCharacterCounter(textarea, options = {}) {
  const maxLength = options.maxLength ?? 280;
  const warnThreshold = options.warnThreshold ?? 0.9;
 

A live character counter for textareas

dom closures accessibility
Intermediate 7 steps

Share this explainer

Here's the card — post it anywhere.

Optional chaining and nullish coalescing in JS — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code