The ?.
is called the optional chaining operator (TC39 Stage 4), it is used when you are not sure whether a nested property exists or not. If you try to use the .
operator to access a property which is undefined
you get a TypeError
.
For example:
const obj = {foo: {} };
//This is safe, results in undefined
console.log(obj?.foo?.bar?.baz);
//This results in Uncaught TypeError: Cannot read property 'baz' of undefined
console.log(obj.foo.bar.baz);
Where as the ??
is called the null coalescing operator (TC39 Stage 3). When you are using falsy values like an empty string ""
or a 0
with a ||
operator the operand on the right hand side of the ||
is returned as the falsy value is ignored.
The ??
comes handy when you don't want that and actually you want to consider the falsy values. If the value on the left is a null
or undefined
only then the value on the right of the ??
is taken:
For example:
const empString = "";
const defaultValue = empString || "A default value";
//Outputs A default value as "" empty string is falsy
console.log(defaultValue);
const actualValue = empString ?? "A default value";
//Does not print the default value as the empString is neither null or undefined
console.log(actualValue);
Same for other falsy values like 0
, false
, in disagreement with the ||
operator which will output the 'default
string:
console.log(false ?? 'default') //false
console.log(0 ?? 'default') // 0
Only for undefined
and null
this will output the default value provided in agreement with the ||
operator:
console.log(undefined ?? 'default') //default
console.log(null ?? 'default') //default