JavaScript - Optional Chaining
Hello there, future JavaScript wizards! ? Today, we're going to embark on an exciting journey into the world of Optional Chaining. Don't worry if you're new to programming – I'll be your friendly guide, and we'll take this step-by-step. By the end of this lesson, you'll be chaining like a pro! Let's dive in!
The Non-existing Property Problem
Imagine you're trying to find a book in a massive library. You know it's supposed to be in the "Science Fiction" section, on the third floor, in the back corner. But what if the library doesn't even have a third floor? Or what if there's no "Science Fiction" section? That's the kind of problem we often face in JavaScript when dealing with nested objects.
Let's look at an example:
const library = {
fiction: {
fantasy: {
books: ['The Hobbit', 'Harry Potter']
}
}
};
console.log(library.fiction.sciFi.books);
If you run this code, you'll get an error: "Cannot read property 'books' of undefined". Why? Because library.fiction.sciFi
doesn't exist! This is where Optional Chaining comes to the rescue.
What is Optional Chaining in JavaScript?
Optional Chaining is like a safety net for your code. It allows you to access nested object properties without worrying if the intermediate properties exist. It's denoted by the ?.
operator.
Let's rewrite our previous example with Optional Chaining:
const library = {
fiction: {
fantasy: {
books: ['The Hobbit', 'Harry Potter']
}
}
};
console.log(library.fiction.sciFi?.books);
Now, instead of throwing an error, this will simply return undefined
. It's like asking, "If sciFi
exists, can you please give me its books
? If not, no worries!"
Optional Chaining with Function Calls
Optional Chaining isn't just for object properties. You can use it with function calls too! Let's say we have a library system where books can be checked out:
const library = {
fiction: {
fantasy: {
checkOut: function(book) {
console.log(`Checking out ${book}`);
}
}
}
};
library.fiction.fantasy.checkOut?.('The Hobbit');
library.fiction.sciFi?.checkOut?.('Dune');
In this example, 'The Hobbit' will be checked out, but nothing will happen with 'Dune' because sciFi
doesn't exist. No errors, just smooth sailing!
Optional Chaining with Expression
You can also use Optional Chaining with square bracket notation. This is useful when your property names are dynamic or contain special characters:
const users = {
'123': { name: 'Alice', age: 30 },
'456': { name: 'Bob', age: 25 }
};
const userId = '789';
console.log(users[userId]?.name);
This will return undefined
because there's no user with ID '789', but it won't throw an error.
Optional Chaining with the "delete" Operator
The delete
operator can also be used with Optional Chaining. This is handy when you want to delete a property that might not exist:
const obj = {
prop: {
innerProp: 'value'
}
};
delete obj.prop?.innerProp;
delete obj.nonExistent?.prop;
The first delete
will work as expected, removing innerProp
. The second one will do nothing, but won't throw an error.
Short-circuiting with Optional Chaining
Optional Chaining has a neat feature called short-circuiting. If the left part of the ?.
is null
or undefined
, the evaluation stops and returns undefined
:
const obj = null;
console.log(obj?.prop?.subProp); // Returns undefined
This is super helpful for avoiding those pesky "Cannot read property of null" errors!
Nullish Coalescing Operator with Optional Chaining
The Nullish Coalescing Operator (??
) works great with Optional Chaining. It allows you to provide a default value if the result of the Optional Chaining is null
or undefined
:
const user = {
name: 'Alice',
details: {
age: 30
}
};
console.log(user.details?.job ?? 'unemployed'); // 返回 'unemployed'
console.log(user.details?.age ?? 'unknown'); // 返回 30
This is perfect for providing fallback values when properties might not exist.
Here's a table summarizing the methods we've covered:
方法 | 語法 | 描述 |
---|---|---|
属性訪問 | obj?.prop |
安全地訪問嵌套對象屬性 |
函數調用 | func?.() |
安全地調用可能不存在的函數 |
表達式 | obj?.[expr] |
安全地訪問具有動態或特殊名稱的屬性 |
刪除操作符 | delete obj?.prop |
安全地刪除可能不存在的屬性 |
短路評估 | obj?.prop?.subProp |
如果任何部分為 null 或 undefined,則停止評估 |
與 Nullish Coalescing 運算符一起使用 | obj?.prop ?? defaultValue |
為 null 或 undefined 結果提供默認值 |
And there you have it, folks! You've just leveled up your JavaScript skills with Optional Chaining. Remember, coding is like building with LEGO – start with the basics, and before you know it, you'll be creating masterpieces. Keep practicing, stay curious, and happy coding! ?????
Credits: Image by storyset