Introduction
Nullish Coalescing, represented by the ?? operator, is a logical operator introduced in JavaScript ES2020. It provides a safe and predictable way to assign default values when dealing with variables that might be null or undefined.
This operator solves a common problem in JavaScript: differentiating between truly missing values (null or undefined) and falsy but valid values (0, '', false). Prior to ??, the || (logical OR) operator was often misused for defaulting, which could lead to bugs and unexpected behavior.
Core Syntax
let result = a ?? b;
- Returns
aif it’s not null or undefined - Otherwise returns
b
This makes it a null-aware defaulting mechanism.
Comparison: || vs ??
Problem with ||
let count = 0;
let result = count || 10;
console.log(result); // 10 ❌ (unexpected)
0is a falsy value, so||returns10- But
0might be a valid input
Solution with ??
let count = 0;
let result = count ?? 10;
console.log(result); // 0 ✅ (expected)
Nullish Values Only: null and undefined
?? does not trigger for falsy values like:
false0''(empty string)NaN
It only checks for:
nullundefined
Example:
console.log(false ?? 'yes'); // false
console.log(0 ?? 42); // 0
console.log('' ?? 'default'); // ''
console.log(null ?? 'missing'); // 'missing'
Use Cases
| Scenario | Example |
|---|---|
| Setting default config values | config.timeout = userTimeout ?? 5000; |
| Reading from forms | let name = input.value ?? 'Anonymous'; |
| Parsing JSON with optional keys | let title = json.title ?? 'Untitled'; |
| Replacing deprecated ` |
Nested Nullish Coalescing
You can chain multiple ?? operators:
let result = value1 ?? value2 ?? value3 ?? 'fallback';
This returns the first defined and non-null value in the chain.
Use in Functions
function greet(name) {
name = name ?? 'stranger';
console.log(`Hello, ${name}!`);
}
This ensures name will only be replaced if it’s explicitly null or undefined.
Combined with Optional Chaining
The ?? operator pairs perfectly with optional chaining (?.) to safely access deeply nested properties.
let city = user?.address?.city ?? 'Unknown';
- If
user,address, orcityisundefinedornull,citywill default to'Unknown'.
Syntax Rules and Gotchas
❗ Parentheses Required When Mixing with || or &&
// ❌ SyntaxError
let value = a || b ?? c;
This is ambiguous because of precedence issues.
✅ Fix:
let value = a || (b ?? c);
Always use parentheses when combining ?? with logical operators.
Operator Precedence
| Operator | Precedence |
|---|---|
. / ?. (member access) | Highest |
?? (nullish coalescing) | 5 |
| ` | |
= (assignment) | 3 |
Note: ?? has higher precedence than || and &&, but lower than arithmetic and comparison operators.
Best Practices
| Best Practice | Reason |
|---|---|
Use for null/undefined defaults only | Avoids logic errors with falsy values |
| Don’t mix with ` | |
| Combine with optional chaining for safety | Avoids runtime errors |
| Don’t overuse or nest deeply | Reduces readability |
TypeScript Support
TypeScript fully supports ?? as of version 3.7.
let age: number | undefined = undefined;
let validatedAge = age ?? 18; // 18
It respects null and undefined as distinct from other falsy values.
Real-World Examples
Environment Variables
const PORT = process.env.PORT ?? 3000;
Only use the default if PORT is undefined or null, not if it’s '' or '0'.
User Settings
const theme = userPreferences?.theme ?? 'light';
Avoids throwing an error if userPreferences is undefined.
Dynamic Values with Safe Fallbacks
function getDiscount(price, discount) {
return price * (discount ?? 1);
}
Avoids multiplying by undefined.
Alternatives in Other Languages
| Language | Equivalent Concept |
|---|---|
| C# | ?? operator (same as JS) |
| Swift | ?? operator (nil coalescing) |
| Kotlin | ?: Elvis operator |
| Python | x if x is not None else y |
| Ruby | `x |
Polyfill or Babel Support?
If you need backward compatibility (pre-ES2020), you can use Babel to transpile the ?? operator into older JavaScript code.
However, there’s no direct polyfill for this operator in native JS engines, because it’s a syntax-level feature.
Common Pitfalls
| Mistake | Explanation |
|---|---|
Using ?? with non-null checks | false ?? 'default' → false, not 'default' |
| Forgetting parentheses | `a |
| Using with older environments | May throw syntax error in ES2019 or earlier |
Summary
| Feature | Description |
|---|---|
| Purpose | Return first defined (non-nullish) value |
| Triggers on | Only null and undefined |
| Safe with falsy? | ✅ Yes (e.g., 0, '', false stay unchanged) |
| Introduced in | JavaScript ES2020 |
| Perfect pair with | Optional chaining (?.) |
Related Keywords
- Default Value
- Falsy Value
- Logical OR
- Null Check
- Null-Safe Operator
- Nullish Value
- Optional Chaining
- Short-Circuit Evaluation
- Type Coercion
- Undefined Handling









