Nullish coalescing operator is a logical javascript operator that was introduced in JavaScript with the launch of ES2020 aka ES11and is symbolized with double question marks (??).
The nullish coalescing operator is a logical operator that accepts two operands – one on its left-hand side and one on its right-hand side and the syntax looks like this:
LeftHandSideOperand ?? RightHandSideOperand
Let’s see where we can use it.
The logic behind the nullish coalescing operator is that it returns its right-hand side operand (RightHandSideOperand) if the left-hand operand (LeftHandSideOperand) is null or undefined, and otherwise returns its left-hand side operand.
Assigning a default value to a variable before ?? existed
The double question mark operator (??) can be compared to the logical operator OR, which is symbolized with ||. Before the nullish coalescing operator (??) was introduced, developers often applied the logical operator OR (||) when they when wanted to assign a default value to a variable. But, there was a problem because the OR operator caused uncertainty due to the fact it is a boolean logical operator, so the operand on the left is coerced to a boolean for the evaluation: the OR operator returns the operand on the right side if the operand on the left side is ANY falsy value, not only null or undefined. Therefore, developers met unexpected behaviors if they considered O, NaN or some other falsy value as a valid value.
let zeroNumber = 0;
let emptyString = "";
// resultNumber will be 77 because number 0 is falsy
let resultNumber = zeroNumber || 77;
// resultString will be Some text... because empty string ("") is falsy
let resultString = emptyString || "Some text...";
console.log(resultNumber);
console.log(resultString);
The nullish coalescing operator solves that problem – it returns operand on the right side if the one on the left side is evaluated to either null or undefined and no other falsy value.
let emptyString = "";
// resultString is now "" (empty string) and not "Some text..."
let resultString = emptyString ?? "Some text...";
console.log(resultString);
It is also important to bring out that the nullish coalescing operator has the fifth-lowest operator precedence, and is located directly below the operator OR and directly above the conditional (ternary) operator.
Short-circuit evaluation
The nullish coalescing operator is short-circuited – just like OR or AND operator – which means that there is minimal evaluation: the expression on the right side is not evaluated if the one on the left-hand side demonstrates to be neither null nor undefined.
Careful when combining The nullish coalescing operator with AND (&&) and OR operators (||)
Remember, if you combine both the AND (&&) and OR operators (||) directly with The double question mark operator (??), Javascript will give you a SyntaxError.
// SytaxError in both cases
null || undefined ?? "Some text...";
true || undefined ?? "Some text...";
However, there is a solution. Wrap the expression on the left of the ?? operator in parentheses. This way you will explicitly indicate the operator precedences:
// no error this time
(null || undefined) ?? "Some text...";
The nullish coalescing operator ?? and the optional chaining operator (?.) have similarities
The nullish coalescing operator (??) manages undefined and null as specific values and the same does the optional chaining operator (?.) – if a reference is null or undefined, the expression short circuits with a return value of undefined. When applied with function calls, the optional chaining operator returns undefined if the given function doesn’t exist. Therefore, it is practical to access a property of an object which may be null or undefined, so the nullish coalescing operator may be used after the optional chaining operator in order to establish a default value when no value is available. However, when you’re accessing values from deeply nested objects in JavaScript, keep in mind this can be vulnerable to errors because some values might not exist, so they’ll evaluate as null or undefined.
let someObject = { aProperty: "Some text..." };
// will display "Some text..."
console.log(someObject.aProperty?.toUpperCase() ?? "Property doesn't exists");
// will display "Property doesn't exists"
console.log(someObject.nonExistingProperty?.toUpperCase() ?? "Property doesn't exists");