Photo by Iker Urteaga on Unsplash
The Ultimate Guide to Default Values in JavaScript: || and ?? Operators Explained
Learn When to Use the Logical OR and Nullish Coalescing Operators.
One of the most common tasks in JavaScript is providing default values for variables that may be falsy or nullish.
Two operators that are commonly used for this are the logical OR (||
) and the nullish coalescing (??
) operators, but they definetely are not the same.
In this post, we'll explore the differences between these two operators and when to use each one.
The Logical OR (||
) Operator
The logical OR (||
) operator is used to provide a default value when a variable is falsy. The falsy values in JavaScript are false
, 0
, ''
(empty string), null
, undefined
, and NaN
.
When using the ||
operator, the first operand is returned if it evaluates to true
; otherwise, the second operand is returned.
Here's an example:
const a = false || 'bar'; // returns 'bar'
const b = '' || 'qux'; // returns 'qux'
const c = null || 'corge'; // returns 'corge'
In this example, a
is assigned the value 'bar'
because false
is falsy; b
is assigned 'qux'
because ''
is falsy, and c
is assigned 'corge'
because null
is falsy as well.
The ||
operator is useful when you want to provide a default value for falsy values, as well as nullish values.
However, it's important to note that the ||
operator can have unintended consequences when the operands are not of the same type, due to JavaScript's type coercion rules. For example:
const foo = '' || 0; // returns 0
Here, the ''
operand is coerced to the number 0
, which is the last operand and is returned. To avoid these issues, it's generally safer to use the nullish coalescing operator (??
) when checking for nullish values.
The Nullish Coalescing (??
) Operator
The nullish coalescing (??
) operator is used to provide a default value when a variable is nullish. The nullish values in JavaScript are null
and undefined
.
When using the ??
operator, the first operand is returned if it is not null
or undefined
; otherwise, the second operand is returned.
const a = null ?? 'bar'; // returns 'bar'
const b = '' ?? 'qux'; // returns ''
const c = undefined ?? 'corge'; // returns 'corge'
In this example, a
is assigned the value 'bar'
because null
is nullish; b
is assigned ''
because ''
is not nullish, and c
is assigned 'corge'
because undefined
is nullish and the second operand is returned.
The ??
operator is useful when you want to provide a default value for nullish values only, without also including falsy values. This can help prevent unintended consequences when using different types of operands, as it only checks for nullish values.
Choosing between ||
and ??
If you want to provide a default value for falsy values in addition to nullish values, you should use the ||
operator. If you only want to provide a default value for null
and undefined
, you should use the ??
operator.
These operators have different use cases and can't always be used interchangeably. Let's contrast the previous examples:
const a = false || 'bar'; // returns 'bar'
const a = null ?? 'bar'; // returns 'bar'
const b = '' || 'qux'; // returns 'qux'
const b = '' ?? 'qux'; // returns ''
const c = null || 'corge'; // returns 'corge'
const c = undefined ?? 'corge'; // returns 'corge'
The result is the same for a
and c
, but look at the result for b
; this happens because ''
is a falsy value and 'qux'
is returned when we use ||
, but ''
is not a nullish value, and then ''
itself is returned when we use ??
.
Real-World Examples
Here are some real-world examples of how the ||
and ??
operators can be used:
Example 1: Providing a default value for a function parameter
function printName(name) {
console.log(`Hello, ${name || 'world'}!`);
}
printName(); // prints "Hello, world!"
printName(''); // prints "Hello, world!"
printName('Alice'); // prints "Hello, Alice!"
In this example, the printName
function uses the ||
operator to provide a default value of 'world'
if name
is falsy. This allows the function to be called without any arguments or with an empty string and still print a default message.
If we had used the ??
operator, it would print "Hello, !"
when passing an empty string. So, the ||
makes more sense here.
Example 2: Providing a default value for a configuration object
javascriptCopy codeconst config = {
apiUrl: process.env.API_URL || 'https://example.com/api',
apiKey: process.env.API_KEY ?? 'default-key',
};
In this example, the config
object uses the ||
operator to provide a default value for apiUrl
if process.env.API_URL
is falsy. It uses the ??
operator to provide a default value for apiKey
if process.env.API_KEY
is nullish.
The ||
is also a better fit in this case, because an empty string would be swapped by a default value, which is important when dealing with environment variables.
Example 3: Using a default value for a missing property
const user = {
name: 'Alice',
age: 30,
};
console.log(user.name || 'Unknown'); // prints "Alice"
console.log(user.email || 'Unknown'); // prints "Unknown"
In this example, the user
object uses the ||
operator to provide a default value of 'Unknown'
for the missing email
property. This allows the program to gracefully handle missing or incomplete data.
But... when to use the ??
operator, then? 🤔
So far in our examples, we demonstrated how the ||
would be a better option, since it takes care of empty strings and that was a wanted behavior in those cases.
You see, while the ||
operator can be useful for providing default values for string parameters, it can lead to unexpected results when used with numbers or booleans. Consider this code:
const value1 = 0 || 42; // returns 42
const value2 = false || true; // returns true
Here, the ||
operator returns the second operand (42
and true
) instead of the falsy first operand (0
and false
). This will most certainly lead to bugs if 0
and false
are valid and expected values.
This is where the ??
operator shines, since it will only provide a default value if the value is null
or undefined
. Let's see:
const value1 = 0 ?? 42; // returns 0
const value2 = false ?? true; // returns false
In this example, the ??
operator returns the first operand (0
and false
) because they are not nullish values.
Let's see a real world example:
function getValueOrDefault(num, defaultValue) {
num = num ?? defaultValue;
return num;
}
console.log(getValueOrDefault(42, 10)); // returns 42
console.log(getValueOrDefault(0, 10)); // returns 0
console.log(getValueOrDefault(null, 10)); // returns 10
console.log(getValueOrDefault(undefined, 10)); // returns 10
In this example, we only use the defaultValue
if num
is null
or undefined
. Pay special attention to the second example, where we pass 0
as num
, which is a perfectly valid number, and it is used instead of the alternative 10
.
So, in general, when working with numbers or booleans, it's usually better to use the ??
operator to avoid unexpected behavior and ensure that valid input values are not treated as falsy.
Conclusion
When choosing between the ||
and ??
operators, it'simportant to consider the behavior of each operator and choose the one that best fits your use case.
In summary, here are some guidelines to keep in mind when using these operators:
Use the
||
operator if you want to provide a default value for falsy values in addition to nullish values.Use the
??
operator if you only want to provide a default value fornull
andundefined
.Avoid using the
||
operator with operands of different types, as it can lead to unintended consequences due to JavaScript's type coercion rules.The
||
is usually better for strings, while the??
is usually better for numbers and booleans.When in doubt, use the
??
operator, as it is safer and more predictable when checking for nullish values.
Happy coding!