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!

JavaScript - Optional Chaining

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