Nullish Coalescing β The Truth About the ?? Operator
After this topic, you will:
Understand the difference between ?? and ||, and be able to decide which one to use when setting default values.
Setting Default Values with ||
const port = config.port || 3000;If config.port is falsy, it uses 3000. This is a common pattern, but there's a catch.
const config = { port: 0, debug: false, name: "" };
const port = config.port || 3000; // 3000 β 0 is falsy
const debug = config.debug || true; // true β false is falsy
const name = config.name || "default"; // "default" β "" is falsy0, false, and "" are valid values, but || treats them all as falsy and overwrites them with the default value. You set the port to 0, but it becomes 3000. You wanted to disable debugging by setting it to false, but it becomes true.
?? Only Checks for null and undefined
const port = config.port ?? 3000; // 0 β remains unchanged
const debug = config.debug ?? true; // false β remains unchanged
const name = config.name ?? "default"; // "" β remains unchangedThe ?? (nullish coalescing operator) only uses the right-hand value if the left-hand value is null or undefined. It treats 0, false, and "" as valid values.
|| β Checks for falsy values (0, "", false, null, undefined, NaN)
?? β Checks for nullish values (only null and undefined)The Difference in Practice
Let's look at a scenario where you're setting default values from an API response:
const response = { total: 0, items: [], message: "" };
// Using ||
const total = response.total || "N/A"; // "N/A" β ignores 0
const msg = response.message || "μμ"; // "μμ" β ignores the empty string
// Using ??
const total = response.total ?? "N/A"; // 0 β correct
const msg = response.message ?? "μμ"; // "" β correctThe same problem occurs when setting default values for function parameters:
function createUser(name, age) {
const userAge = age || 25; // What if age is 0? It becomes 25.
const userAge2 = age ?? 25; // What if age is 0? It remains 0.
}You Can't Mix ?? and ||
// SyntaxError
const value = a || b ?? c;If you mix ?? and || (or &&) without parentheses, you'll get a syntax error. JavaScript explicitly prohibits this because the precedence is ambiguous. You need to use parentheses:
const value = (a || b) ?? c;Choosing Which to Use
It's simple:
- If you want to provide a default value when the value is "absent", use
??. - If you want to provide a default value when the value is "empty", use
||.
"Absent" and "empty" are different. 0 is an empty value, but it still exists. null is truly absent.
In most cases, ?? is more accurate to your intention. Only use || when you genuinely want to replace 0 and "" with default values.
Key Takeaway
??applies the default value only when the value isnullorundefined.||applies the default value to all falsy values (0, false, ""). If you want to set a default value when a value is "absent",??is the right choice.