JavaScript is one of the most popular computer languages of all time, one of the reasons for this is the highly intuitive syntax of JavaScript. That's not even the best part, the best part is that a lot of new features are added to the language regularly.
Today we will see some of those new features help us with writing more intuitive code.
Nullish coalescing operator (??)
The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null
or undefined
, and otherwise returns its left-hand side operand.
false || '@sun_anshuman' // returns '@sun_anshuman'
false ?? '@sun_anshuman' // returns false
0 || '@sun_anshuman' // returns '@sun_anshuman'
null || '@sun_anshuman' // returns '@sun_anshuman'
null ?? '@sun_anshuman' // returns '@sun_anshuman'
undefined ?? '@sun_anshuman' // returns '@sun_anshuman'
The problem with ||
is that its a boolean operator so it coerces the left-hand operand to a boolean before evaluating, hence making both 0 and '' a false
.
Use case by example
Let's assume you are building a game where the minimum score is 0 and you consider -1 an invalid score.
So before you update a user's score you would like to make sure it is set to a valid value or the defined invalid score.
// the server returns 0
let score = fetchScoreFromServer();
// we only want the score to be -1 only if the score
// is undefined or null because 0 is a valid value
const finalScore = score || -1;
// but this will give us the invalid value even if,
// the first operand (0) is a valid value, leading to a bug
How to solve this, you ask? (I know you know it by now, haha)
let score = fetchScoreFromServer(); // returns 0 again
const finalScore = score ?? -1;
// finalScore stays score (0 in this case),
// unless the server returned null or undefined
Logical nullish assignment (??=)
The logical nullish assignment (x ??= y) operator only assigns if x is nullish (null
or undefined
).
let user = { name: "anshuman_bhardwaj" };
user.twitter_name ??= "@sun_anshuman"; // assigns '@sun_anshuman'
console.log(user); // {name: "anshuman_bhardwaj", twitter_name: "@sun_anshuman"}
This is basically an assignment operation based on the ??
operator.
Use case by example
// the above example can be rewritten like this
let finalScore = fetchScoreFromServer(); // returns 0 again
finalScore ??= -1;
// keeps value of 0
Another good place to use ??
would be while referencing object properties and using default value. In which case we can use Logical nullish assignment ??=
to give default values to undefined
properties.
const user = { email: 'anshuman_bhardwaj@dev.to', company: '' }
// assign user.name to email username if it's undefined
user.name ??= email.split("@")[0]
// make company Canoo if company not available on user
user.company ??= 'Canoo'
// this time company stays empty string
in operator
The in operator returns true if the specified property is in the specified object or its prototype chain.
const user = { email: 'anshuman@gmail.com' }
'email' in user // return true
'name' in user // return false
You remember the time you were using undefined
values because the referenced key was missing from Object.
It is worth noting that,
If you set a property to undefined but do not delete it, the in operator returns true for that property.
Use case by example
A good use case is to run sanity checks before running operations on an object's properties to avoid doing undefined checks and mistakes.
// we have an user object
let user = { email: "anshuman_bhardwaj@dev.to" };
// now we want to assign it a name if its not available
// checks if user has email
if ("email" in user) {
// checks if user has name
if (!("name" in user)) {
user["name"] = user.email.split("@")[0];
} else {
console.log("Welcome user: " + user.name);
}
} else {
console.error("User does not have required property: email");
}
Using in on an array checks if the given index is an empty slot or not
const emptyList = new Array(5)
empties[2] // returns undefined
2 in empties // returns false
empties[2] = 'anshuman_bhardwaj'
2 in empties // returns true
Optional chaining (?.)
The ?.
operator is like the . chaining operator, except that instead of causing an error if a reference is (null or undefined), the expression short-circuits with a return value of undefined.
let user = { name: 'anshuman' }
user.address.zipcode // TypeError
user.addess?.zipcode // returns undefined
It is worth noting that,
- When used with function calls, it returns undefined if the given function does not exist.
- Optional chaining cannot be used on a non-declared root object but can be used with an undefined root object.
Use case by examples
// user can be null or an Object containing email
const user = getUserFromDev()
// if we do this it will run fine when user is an Object
// but when user is null this will give a TypeError
console.log(user.email)
// we can fix this by using optional chaining
console.log(user?.email)
// logs the actual user email when user is an Object
// logs undefined if user is null but doesn't crash
Conditional ternary operator (?)
The ternary operator checks whether the condition specified is true, if it's true then return the first expression else return the second expression.
x ? y : z
, means if x is true return y else return z.
let user = { age: 22 }
user['status'] = user.age > 18 ? 'adult' : 'minor'
// user.status is 'adult'
This operator is not specific to JavaScript, I first used it in C++.
Use case by example
let user = { email: "anshuman_bhardwaj@dev.to" };
// lets consider this code, simple enough?
if ("email" in user) {
user["name"] = user.email.split("@")[0];
} else {
user["name"] = "Anonymous";
}
// we can make it even simpler by using ternary
user["name"] = "email" in user ? user.email.split("@")[0] : "Anonymous";
Using ternary is a personal preference, it's good for doing inline expressions otherwise everything can be put as if-else
Bonus
Here are some examples with mix and match of the above features, let's see who all can answer correctly down in the comments.
// consider the examples independent of each other
const user = { email: 'anshuman_b@dev.to', lastName: undefined }
// 1
user["firstName"] = "email" in user
? user.email.split("_")[0]
: "Anonymous";
// 2
user["familyName"] ??= 'Bhardwaj'
// 3
console.log('lastName' in user)
// 4
console.log('' ?? '@sun_anshuman')
Learn more
You can also watch this YouTube video where I explain these examples
You can also fork the CodeSandBox to try out examples.
I hope you enjoyed reading this article as much as I enjoyed writing it!
For more such content, please follow me on Twitter
Until next time
Top comments (0)