Suggest an editImprove this articleRefine the answer for “Optional chaining operator”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Optional chaining (`?.`) is an ES2020 operator that lets you safely access properties, methods and elements even when part of the chain is `null` or `undefined`.** If the value before `?.` exists, the property is returned; if it is `null` or `undefined`, the whole expression returns `undefined` and the code does not crash with a `TypeError`. It comes in three forms: `obj?.prop`, `obj.method?.()` and `arr?.[0]`. It is often paired with `??`, which supplies a default value. ```javascript const user = { profile: { name: 'Alice' } }; console.log(user.address?.city); // undefined, no error console.log(user.address?.city ?? '-'); // "-" ``` **Key point:** `obj?.prop` is shorthand for `obj == null ? undefined : obj.prop`, so the check for `null` and `undefined` is built into the property access itself.Shown above the full answer for quick recall.Answer (EN)Image**Optional chaining (`?.`) is a modern operator (ES2020) that lets you safely access object properties even when part of the chain is `undefined` or `null`.** Instead of a long run of guards you write a single symbol and get `undefined` where you used to get a `TypeError`. ## Theory ### TL;DR - `?.` short-circuits the chain as soon as the left side is `null` or `undefined` and returns `undefined`. - Three forms: property access `obj?.prop`, method call `obj.method?.()`, index access `arr?.[0]`. - The equivalent under the hood: `obj == null ? undefined : obj.prop`. - It checks only for `null` and `undefined`, not for "empty" values like `0`, `''` or `false`. - It pairs nicely with `??` for a default value. - It cannot be placed on the left-hand side of an assignment. ### Quick example ```javascript const user = { profile: { name: 'Alice' } }; console.log(user.profile?.name); // "Alice" console.log(user.address?.city); // undefined (no error) ``` ### The problem without optional chaining Suppose we have a nested object: ```javascript const user = { profile: { name: 'Alice' } }; ``` If we try to reach a field that does not exist: ```javascript console.log(user.address.city); // TypeError: Cannot read properties of undefined ``` > The error happens because `user.address` is `undefined`, and trying to read `undefined.city` breaks the code. The solution, the `?.` operator: ```javascript console.log(user.address?.city); // undefined (no error) ``` If the value **before** `?.` exists, the property is returned. If it is `undefined` or `null`, the result is `undefined` and the program does not crash. ### Forms of the syntax **1. Property access** ```javascript user?.profile?.name // "Alice" user?.address?.city // undefined ``` **2. Method access** ```javascript user.sayHi?.(); // calls the method if it exists ``` **3. Array element access** ```javascript const arr = null; console.log(arr?.[0]); // undefined (no error) ``` **An example with API data** ```javascript const response = { user: { name: 'Alice', address: null } }; console.log(response.user?.address?.city); // undefined ``` Without `?.` you would have to write long guards: ```javascript response && response.user && response.user.address && response.user.address.city ``` ### Optional chaining with nullish coalescing These two operators are often used together: ```javascript const city = user.address?.city ?? 'Not specified'; console.log(city); // "Not specified" ``` - `?.` accesses the property safely. - `??` supplies a default value when the result is `undefined` or `null`. Unlike `||`, the `??` operator does not replace valid falsy values: `0 ?? 10` gives `0`, while `0 || 10` gives `10`. ### What it does under the hood ```javascript obj?.prop // equivalent to: obj == null ? undefined : obj.prop ``` The loose comparison `== null` is true for both `null` and `undefined`, so one operator covers both cases. An important detail: the chain short-circuits, so in `a?.b.c` the rest of the expression is not evaluated at all when `a` is `null`. ### Where you can use it | Situation | Example | Result | | --- | --- | --- | | Object property | `user?.name` | `'Alice'` or `undefined` | | Nested objects | `user?.address?.city` | safe | | Method call | `user.method?.()` | called if the method exists | | Array element | `arr?.[0]` | the first element or `undefined` | ### Where you cannot use it ```javascript // not allowed on the left of an assignment user?.name = 'Alex'; // SyntaxError // not an existence check: it yields undefined, not false if (user?.missing) { /* ... */ } ``` ### Summary table | What it does | How it works | | --- | --- | | **Optional chaining (`?.`)** | Accesses a property safely without throwing | | **Returns** | `undefined` when it meets `null` or `undefined` | | **Used for** | accessing nested properties, methods and elements | | **Combined with** | `??` most of the time, for default values | ### Common mistakes - **Putting `?.` in every link "just in case".** It masks real bugs: if `user` always exists by contract, `user?.profile` only hides a data problem. - **Confusing it with an "empty value" check.** `?.` reacts only to `null` and `undefined`; `0`, `''` and `false` pass through as ordinary values. - **Combining `??` with `||` or `&&` without parentheses.** `a ?? b || c` is a `SyntaxError`, explicit parentheses are required. - **Forgetting that the chain can still throw after a `?.`.** In `user?.address.city` only `user` is guarded; if `address` is `undefined`, you get a `TypeError`. - **Calling a method as `user?.sayHi()` instead of `user.sayHi?.()`.** The first form only guards against a missing `user`, not against a missing method. - **Using `?.` on the left of an assignment.** That is a syntax error, the operator is read-only.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.