Nullish coalescing and optional chaining in JavaScript

Nullish coalescing and optional chaining in JavaScript

Nullish Coalescing operator ??

nullish coalescing operator is represented by ??

This operator checks if the left operand is null or undefined and return the first value on the right if the left operand is one of these value

why do we need this operator?

In JS, we have a short circuit OR || operator which is similar to nullish coalescing.

let person = 0 || "falsy value"    //"falsy value"

let person = undefined || "falsy value"    //"falsy value"

let person = "" || "falsy value"    //"falsy value"

the major difference between them is short circuit OR operator checks all falsy values (0, "", NaN, null, undefined) whereas nullish coalescing checks only for nullish values(null, undefined)

both these operators have the same precedence level so if we are using them together we need to give () to avoid error

suppose we have to track where 0 is an acceptable value. In this case, short circuit OR will treat 0 as a falsy value and always return the first truthy value it encounters. Nullish coalescing operator is made for such cases. it will check only for null and undefined values, else return the left operand. let's see code example to better understand this

const person1 = 0
const person2 = undefined

const checkAttemptsUsingOr = (person) =>{
 console.log(person || "no attempts")
}
// short circuit OR will treat 0 as falsy value, so it is skipped
checkAttemptsUsingOr(person1)  //'no attempts'
checkAttemptsUsingOr(person2)  //'no attempts'


const checkAttemptsUsingNullish = (person) =>{
  console.log(person ?? "no attempts")
}
// nullish coalescing will check for only null/undefined, 
//0 is a "defined" value
checkAttemptsUsingNullish(person1)  //0
checkAttemptsUsingNullish(person2)  //'no attempts'

we can chain multiple nullish coalescing operators. in this case, the first value which is not null/undefined is returned.

const first = null
const second = undefined
const third = "okay"

console.log(first ?? second ?? third) //"okay"

Optional chaining (?.) operator

Optional chaining is represented by ?.

optional chaining is used to safely access nested properties/methods on an object that can be nullish(null/undefined)4

usually, when we try to access a property of a null/undefined object we get an error. in such cases we can use optional chaining to safely access the property, optional chaining will return an undefined value when we try to access the property on a nullish object.

the key point to remember is that optional chaining short circuits the operations and returns undefined the moment we encounter a nullish value. if the object we are trying to access the property from is null/undefined, further evaluation will not happen.

let person = {
    name: "Jay Rajput",
    age: 23,

}
//address is undefined, we are trying access property city of an undefined object
console.log(person.address?.city )     //undefined

we can use optional chaining with object methods and bracket notation as well.

//optional chaining with object method
let person = {
  getName:()=>{
    console.log("Hello I am Jay")
  }
}
//getAge method does not exists
console.log(person.getAge?.())   //undefined

//optional chaining with bracket notation
const key = "time"

const obj = {
  id:1,
  value: "pokemon",
  time: "5.30 PM"
}

console.log(obj?.[key])   //'5.30 PM'

optional chaining key points:

do not use overuse optional chaining

we should use optional chaining only when we know that the object we are trying to access is null or undefined. Otherwise, when we expect an object to have a value but we get nullish value, we will not get an error.

//we know user object exists but it's address property can be nullish

//correct 
user.address?.city

//incorrect: nullish user object expected to exits but we wont get error if it is null because of optional chaining
user?.address?.city

optional chaining does not work on the left-hand side of an assignment

we cannot use optional chaining on the left side of the assignment as a variable name, as it will return undefined and we cannot have undefined keyword as a variable name

const user = {
  name:"jay"
}

user?.name = "rahul"
//SyntaxError: Invalid left-hand side in assignment expression.

the object we are trying to access should be declared before we use optional chaining

we cannot use optional chaining on an undeclared object.

console.log(user?.name)
//ReferenceError: user is not defined

conclusion

both nullish coalescing and optional chaining operators are used for gracefully handling nullish values. We can also use these operators in combination to safely check for nullish values and set a default value

let user = {
    id:1,
    name:"jay"
}

let location = (user?.address) ?? "location unknown"
console.log(location)    //'location unknown'