Unmasking the Mystery: ?? vs || in JavaScript
JavaScript offers two powerful tools for providing default values: the logical OR (||) and the nullish coalescing (??) operators. While they might seem similar at first glance, understanding their distinct behaviors is crucial for writing clean, efficient, and predictable code.
In this guide, we’ll dive into the nuances of these operators, exploring when to use each one and why. Let’s start by understanding the basics.
1. Understanding the Operators
The Logical OR (||) Operator
How it works
The logical OR operator (||) is used to combine two boolean values. It returns true
if at least one of the values is true
. However, in JavaScript, it has a broader use: it can be used with any data type.
When used in expressions with non-boolean values, the logical OR operator returns the first truthy value it encounters. If all values are falsy, it returns the last value.
When it returns the right-hand operand
The logical OR operator will return the right-hand operand in the following cases:
- The left-hand operand is
false
. - The left-hand operand is
null
. - The left-hand operand is
undefined
. - The left-hand operand is
0
. - The left-hand operand is an empty string (“”).
- The left-hand operand is
NaN
(Not a Number).
Examples
let x = 0; let y = "hello"; let z = null; console.log(x || "default"); // Output: "default" (x is falsy) console.log(y || "default"); // Output: "hello" (y is truthy) console.log(z || "default"); // Output: "default" (z is null, which is falsy)
The Nullish Coalescing (??) Operator
How it works
The nullish coalescing operator (??) is a newer addition to JavaScript. It provides a way to check if a value is either null
or undefined
. If it is, it returns the right-hand operand. Otherwise, it returns the left-hand operand.
When it returns the right-hand operand
The nullish coalescing operator will only return the right-hand operand if the left-hand operand is:
null
undefined
Examples
let x = 0; let y = null; let z = "hello"; console.log(x ?? "default"); // Output: 0 (x is not null or undefined) console.log(y ?? "default"); // Output: "default" (y is null) console.log(z ?? "default"); // Output: "hello" (z is not null or undefined)
While the logical OR operator considers many values as falsy, the nullish coalescing operator only checks for null
or undefined
. This makes it more specific in its behavior.
2. Key Differences Between || and ??
When to Use Which Operator
While both the logical OR (||) and nullish coalescing (??) operators can provide default values, their behaviors differ significantly.
Logical OR (||)
- Use when: You want to provide a default value for any falsy value (including
0
,''
,false
). - Example:
let age = 0; let defaultAge = 18; let finalAge = age || defaultAge; // finalAge will be 18
Nullish Coalescing (??)
- Use when: You specifically want to handle only
null
orundefined
values. - Example:
let user = null; let defaultUser = { name: 'Guest' }; let finalUser = user ?? defaultUser; // finalUser will be { name: 'Guest' }
Summary Table
Operator | Returns right-hand operand when | Example |
---|---|---|
Left-hand operand is falsy (null, undefined, 0, ”, false, NaN) | ||
?? | Left-hand operand is null or undefined | let value = x ?? 'default'; |
Remember: The key difference lies in how they treat falsy values. ||
considers many values as falsy, while ??
is more specific, only checking for null
or undefined
.
3. Practical Use Cases
Logical OR (||)
Scenario: Default values for optional parameters
function greet(name) { console.log(`Hello, ${name || 'stranger'}!`); } greet('Alice'); // Output: Hello, Alice! greet(); // Output: Hello, stranger!
Scenario: Short-circuiting for conditional logic
const user = { name: 'Bob' }; const greeting = user && user.name ? `Hello, ${user.name}!` : 'Hello!'; console.log(greeting); // Output: Hello,Scenario: Short-circuiting for conditional logicBob!
Best practices:
- Use
||
when you want to provide a default value for any falsy value. - Be aware of potential side effects if the right-hand operand has side effects.
- Consider using nullish coalescing (??) for more specific null or undefined checks.
Nullish Coalescing (??)
Scenario: Handling optional properties
const user = { name: 'Charlie' }; const fullName = user?.name ?? 'Unknown'; console.log(fullName); // Output: Charlie const emptyUser = {}; const emptyUserName = emptyUser?.name ?? 'Unknown'; console.log(emptyUserName); // Output: Unknown
Scenario: Default values for optional chaining
const address = { street: '123 Main St' }; const street = address?.street ?? 'No street information'; console.log(street); // Output: 123 Main St const noAddress = null; const noStreet = noAddress?.street ?? 'No address'; console.log(noStreet); // Output: No address
Best practices:
- Use
??
when you specifically want to handlenull
orundefined
values. - Combine with optional chaining (?.) for safer property access.
- Avoid unnecessary nesting of
??
operators.
Additional considerations:
- For more complex logic involving multiple conditions, consider using ternary operators or if-else statements.
- Always test your code thoroughly to ensure the desired behavior.
4. Conclusion
The logical OR (||) and nullish coalescing (??) operators are valuable tools in a JavaScript developer’s arsenal for providing default values. While they might seem similar, understanding their distinct behaviors is crucial for writing clear, efficient, and predictable code.
The logical OR operator is versatile and can handle various falsy values, making it suitable for providing defaults in a broad range of scenarios. However, its behavior with falsy values other than null
or undefined
can sometimes lead to unexpected results.
The nullish coalescing operator, on the other hand, is more specific, focusing solely on null
or undefined
values. This makes it ideal for handling optional properties and avoiding unintended consequences with other falsy values.