In JavaScript every value is either truthy or falsy in a boolean context. The nullish coalescing (??) and optional chaining (?.) operators provide safe, precise handling of null/undefined.
There are exactly eight falsy values: false, 0, -0, 0n (BigInt zero), '' (empty string), null, undefined, and NaN. Everything else — including '0', 'false', [], and {} — is truthy. The || operator returns the right side when the left is FALSY, which is a bug when 0 or '' are valid values. ?? returns the right side only when the left is null or undefined, preserving 0 and ''. Optional chaining ?. short-circuits to undefined instead of throwing when accessing a property/method on null/undefined (user?.address?.city, arr?.[0], fn?.()). Together they replace verbose guards with concise, correct code.
Reading a config: const timeout = config.timeout ?? 30000; keeps an intentional timeout of 0, whereas config.timeout || 30000 would wrongly replace 0 with 30000. And const city = response?.data?.address?.city avoids a crash when any level is missing in an API response.
Why can const port = config.port || 3000 be a bug, and how does ?? fix it?