Introduction
The double question mark (??
) is a shorthand operator in JavaScript that is used as a null-coalescing operator. This means that it returns the first operand if it is not null or undefined, and otherwise returns the second operand. This can be useful for providing default values for variables that may be null or undefined.
In this article, we will describe what the double question mark does and how to use it.
Using the double question mark in JavaScript
Here is an example of how the double question mark operator can be used:
let someVariable = null;
let someVariable2 = "User One";
// Without the null-coalescing operator
let result = someVariable !== null ? someVariable : "default value";
// With the null-coalescing operator
let result2 = someVariable2 ?? "default value";
console.log(result, result2);
Output
default value User One
In the example above, the result
variable will be assigned the value of someVariable
if it is not null or undefined and will be assigned the default value of 'default value'
if someVariable
is null
or undefined
. For the result2
variable, it will be assigned the value of someVariable2
because it is not null
. This can be useful for avoiding runtime errors when working with variables that may not always have a defined value.
Here are a few more examples of how the double question mark operator can be used in JavaScript:
// If the "user" variable is defined, use its value,
// otherwise use the default value of "Guest"
let user = "John Doe";
let username = user ?? "Guest";
// If the "shoppingCart" variable is defined and not empty,
// return its length, otherwise return 0
let shoppingCart = [];
let cartSize = shoppingCart.length ?? 0;
// If the "imageUrl" variable is defined and not null,
// use its value, otherwise use the default value of "<https://example.com/default.jpg>"
let imageUrl = null;
let imgSrc = imageUrl ?? "<https://example.com/default.jpg>";
console.log(username, cartSize, imgSrc);
Output
John Doe 0 <https://example.com/default.jpg>
We can use it in cases where we want the user variable to be defined by a default value if the user doesn’t present one. Another example can be in terms of the image profile image.
First-Defined (??)
The first-defined operator ??
evaluates to its first defined operand: if its left operand is not null and not undefined, it returns that value. Otherwise, it returns the value of the right operand. Like the &&
and ||
operators, ??
is short-circuiting: it only evaluates its second operand if the first operand evaluates to null or undefined
. If the expression a has no side effects, then the expression a ?? b
is equivalent to:
(a !== null && a !== undefined) ? a : b
??
is a useful alternative to ||
when you want to select the first defined operand rather than the first truthy operand. Although ||
is nominally a logical OR operator, it is also used idiomatically to select the first non-falsy operand with code like this:
// If maxWidth is truthy, use that. Otherwise, look for a value in
// the preferences object. If that is not truthy, use a hardcoded constant.
let max = maxWidth || preferences.maxWidth || 500;
The problem with this idiomatic use is that zero, the empty string, and false
are all falsy values that may be perfectly valid in some circumstances. In this code example, if maxWidth
is zero, that value will be ignored. But if we change the ||
operator to ??
, we end up with an expression where zero is a valid value:
// If maxWidth is defined, use that. Otherwise, look for a value in
// the preferences object. If that is not defined, use a hardcoded constant.
let max = maxWidth ?? preferences.maxWidth ?? 500;
Here are more examples showing how ??
works when the first operand is falsy. If that operand is falsy but defined, then ??
returns it. It is only when the first operand is “nullish” (i.e., null
or undefined
) that this operator evaluates and returns the second operand:
let options = { timeout: 0, title: "", verbose: false, n: null };
options.timeout ?? 1000 // => 0: as defined in the object
options.title ?? "Untitled" // => "": as defined in the object
options.verbose ?? true // => false: as defined in the object
options.quiet ?? false // => false: property is not defined
options.n ?? 10 // => 10: property is null
Note that the timeout, title, and verbose expressions here would have different values if we used ||
instead of ??
.
The ??
operator is similar to the &&
and ||
operators but does not have higher precedence or lower precedence than they do. If you use it in an expression with either of those operators, you must use explicit parentheses to specify which operation you want to perform first:
(a ?? b) || c // ?? first, then ||
a ?? (b || c) // || first, then ??
a ?? b || c // SyntaxError: parentheses are required
The ??
operator is defined by ES2020, and as of early 2020, is newly supported by current or beta versions of all major browsers. This operator is formally called the “nullish coalescing” operator, but I avoid that term because this operator selects one of its operands but does not “coalesce” them in any way that I can see.
Summary
As you can see, the double question mark operator can be a useful shorthand for providing default values for variables in JavaScript. It can help you avoid runtime errors and make your code more concise and readable.
It's important to note that the double question mark operator is a relatively new addition to JavaScript, and may not be supported in all browsers or environments. If you need to support older browsers or environments, you may want to use a different approach for handling null or undefined values.
Reference
Nullish coalescing operator (??) - JavaScript | MDN (mozilla.org)