JavaScript · ES2020

ES11 Interactive Hub — ECMAScript 2020

The biggest one for daily coding: optional chaining (?.), nullish coalescing (??), BigInt, dynamic import, Promise.allSettled, globalThis. Every modern codebase uses these.

Experience
0 XP
Course completion0%

Optional chaining (?.)

Core topic

Medium6 min

💡 Concept summary

Safely access nested properties — automatically returns undefined if the access chain hits null/undefined partway through.

🤔 Why do you need this feature?

Accessing nested data from an API often hits null/undefined in the middle of the chain, causing "TypeError: Cannot read property of undefined". You had to check every level with && which is very verbose. Optional chaining solves this with a single "?." token.

Before (old style)Verbose / clunky
// Manual checking in ES5
var user = { profile: { address: null } };

// Must check every level
var city = user && user.profile && user.profile.address && user.profile.address.city;
console.log(city); // undefined

// Calling a function also needs a check
var result = obj && obj.foo && typeof obj.foo === 'function' && obj.foo();
ES11 (Modern)Optimal & recommended
// Optional chaining "?." in ES11
const user = { profile: { address: null } };

const city = user?.profile?.address?.city;
console.log(city); // undefined (safe!)

// Call a function if it exists
obj?.foo?.();      // no error if foo is absent
arr?.[0];          // safely access an array element
obj?.method?.(arg); // call a method with an argument

// Combine with nullish coalescing
const name = user?.profile?.name ?? "Guest";
Got it down? Try running real code or take the quiz!

ES11 Quick Reference

Quick syntax overview + copy snippets

Optional chaining (?.)

Safely access nested properties — automatically returns undefined if the access chain hits null/undefined partway through.

const user = { profile: { address: null } };
const city = user?.profile?.address?.city;
console.log(city); // undefined (safe!)
...
Nullish coalescing (??)

The "??" operator provides a fallback ONLY when the left-hand value is null or undefined — unlike ||, which treats all falsy values as triggering the fallback.

const count = 0;
const fallback1 = count ?? 10;
console.log(fallback1); // 0 (correct!)
...
BigInt

A new primitive data type for integers larger than Number.MAX_SAFE_INTEGER (2^53 - 1).

const big = 9007199254740993n; // 'n' suffix
console.log(big); // 9007199254740993n (accurate!)
const big2 = BigInt("99999999999999999");
...
Dynamic import()

The "import()" syntax looks like a function and returns a Promise — allowing modules to be lazy-loaded conditionally or on demand.

button.addEventListener('click', async () => {
    const { renderChart } = await import('./chart.js');
    renderChart(data);
...
Promise.allSettled()

Waits for all promises to settle (whether they succeed or fail) and returns an array with the detailed result of each promise.

const results = await Promise.allSettled([
    fetch('/a'),
    fetch('/b'),
...
globalThis

A standardized reference to the global object — works in every environment: Browser (window), Node.js (global), Web Worker (self), Deno.

globalThis.myLib = { version: '1.0' };
console.log(globalThis.myLib);
if (typeof globalThis.fetch === 'undefined') {
...