?? vs || — The Important Difference
`||` treats 0, ”, false as falsy. `??` only checks `null` and `undefined`. Use ?? for default values.
❌ Logical OR (||) Trap
const count = userInput || 10; // If userInput = 0 → count = 10 (WRONG!) const name = userName || 'Guest'; // If userName = '' → name = 'Guest' (WRONG!) const enabled = isEnabled || true; // If isEnabled = false → enabled = true (WRONG!)
✅ Nullish Coalescing (??)
const count = userInput ?? 10; // If userInput = 0 → count = 0 (CORRECT!) // If userInput = null → count = 10 const name = userName ?? 'Guest'; // If userName = '' → name = '' (CORRECT!) // If userName = null → name = 'Guest' const enabled = isEnabled ?? true; // If isEnabled = false → enabled = false (CORRECT!) // If isEnabled = null → enabled = true
📝 When to Use Which
// Use ?? when 0, '', false are valid values
const volume = settings.volume ?? 50; // volume can be 0 (muted)
const name = user.name ?? 'Anonymous'; // name can be empty string
const isAdmin = user.role ?? false; // role could be empty
// Use || for truthy fallback
const displayName = user.nickname || user.name || 'Guest';
const apiUrl = process.env.API_URL || 'https://default.api.com';
// Combining ?? with &&, ||
const value = (a ?? b) || c;
// Nullish assignment (??=)
let options = {};
options.timeout ??= 3000; // Only sets if undefined/null
options.retries ??= 3;
✅ Real-World Examples
// API response handling
const pageSize = response.data?.pageSize ?? 20;
const sortOrder = response.data?.sortOrder ?? 'desc';
const filters = response.data?.filters ?? {};
// Form inputs
const age = parseInt(input.value) ?? 0; // 0 is valid age
// Configuration with defaults
const config = {
retryCount: userConfig.retryCount ?? 3,
timeout: userConfig.timeout ?? 5000,
enableCache: userConfig.enableCache ?? true // false is valid
};
// Optional chaining + nullish coalescing
const city = user?.address?.city ?? 'Unknown';
💡 Browser Support
- Chrome 80+ ✅
- Firefox 72+ ✅
- Safari 13.1+ ✅
- Node.js 14+ ✅
- TypeScript 3.7+ ✅
“Bug: Volume slider defaulted to 50 when user set to 0. Used ||. Fixed with ??. Took 2 hours to find. Never using || for defaults again.”
