New JavaScript proposal: optional chaining


Optional chaining

This is a new proposal. Old browsers may need polyfills.

Optional chaining ?.(optional chain, hereinafter referred to as OC) is a safe way to access nested object properties, even if a property does not exist at all.


A common problem in JavaScript is that if the address in the user information can be filled in or not, we cannot safely access a property of the address:

let user = {}; //  The user may not fill in the address

alert(user.address.street); //  report errors

Or in the following case, in web development, we may need to obtain a DOM element, but the DOM element may not exist:

//When the result of queryselector (...) is null, the program will report an error
let html = document.querySelector('.my-element').innerHTML;

At OC?.Before it appeared, we generally solved it through logic and operation:

let user = {}; //  User without address

alert( user && user.address && user.address.street ); //  Undefined (no error will be reported)

Using logic and operators can ensure that all parts of the expression can be executed correctly, but the writing method is cumbersome.

Optional chain

OC ?.It can make the code simple when the value in front of it isundefinedOrnullThe execution of the code is immediately blocked and returnedundefined

Through OC, we can safely access the user’s address:

let user = {}; //  A user without an address

alert( user?.address?.street ); //  Undefined (no error will be reported)

even ifuserThe object does not exist, and there will be no error when using OC to access its address attribute:

let user = null;

alert( user?.address ); // undefined
alert( user?.address.street ); // undefined

It should be noted that OC only allows the adjacent parts in front of it to be optional, excluding further values.

In the code above,user?.Only alloweduserThis object isnullorundefined
On the other hand, ifuserIf this object really exists, thenuser.addressThis property must exist, otherwise it cannot be accesseduser?.address.streetAn error will be reported at the second point.

Do not overuse OC
We should use it only if we want a value that may not exist?.
For example, according to our code logic,userObject must exist, butaddressProperty is optional, souser.address?.streetIs a better choice.
Therefore, due to other reasonsuserObject isundefinedCan be quickly discovered. Otherwise, bugs will become harder to find

be located?.Variables before must be declared
IfuserThis variable is not declared at all, souser?.anythingAn error will be triggered:

// ReferenceError: user is not defined

There must be a variable declaration statement herelet/const/var, OC is not valid for undeclared variables

short circuit

As mentioned above, in OC?.The value of the first part of isnullorundefinedThe execution will be stopped immediately.
Therefore, if there is a function call or other operation behind it, it will not be executed.

let user = null;
let x = 0;
user?. sayHi(x++); //  I can't do anything
alert(x);   //  0, the value does not increase automatically

Other usage: (),?. []

OC is not an operator, but a special syntax sugar, so it can be shared with function calls and brackets.

For example,?.()Can be used to execute a function that may not exist.

In the following code, some users haveadminMethod, some users do not:

let user1 = {
    admin() {
        alert("I am admin");

let user2 = {};

user1.admin?.(); // I am admin

We first use some grammar to getadminMethod, because the user object must exist, we can access it safely;
Then use?.()Check the left side. If the admin method exists, execute it (for example, user1). Otherwise, stop the execution without reporting an error (for example, user2).

?.Syntax can also be used when we need to access properties through brackets. It can be used to safely access the properties of an object that may not exist yet:

let user1 = {
    firstName: "John"

let user2 = null; //  If this user cannot be authorized now

let key = "firstName";

alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined

alert( user1?.[key]?.something?.not?.existing ) // undefined

?.Can also work withdeleteOperator sharing

delete user?. name;  //  Delete the user name if the user exists

use?.You can delete and read, butNoPerform assignment operation
To the left of the assignment operator,?.invalid

//The following code assumes that the name attribute needs to be re assigned when the user exists
user?. name = "John"; //  report errors
//Equivalent to undefined = "John"


OC ?.There are three forms:

  1. obj?.prop-IfobjIf it exists, returnobj.propOtherwise, returnundefined
  2. obj?.[prop]-IfobjReturn if presentobj[prop]Otherwise, returnundefined
  3. obj?.method()-IfobjCalled if it existsobj.method()Method, otherwise returnundefined

These forms are very intuitive and easy to use.?.Check that the value on the left isnullorundefine, if not, continue.

By chain?.Nested objects can be accessed safely.

We should use it only if the value on the left may not exist?.In this way, it is easier to find the problem when an error occurs.

Reference link:………


Recommended Today

Seven Python code review tools recommended

althoughPythonLanguage is one of the most flexible development languages at present, but developers often abuse its flexibility and even violate relevant standards. So PythoncodeThe following common quality problems often occur: Some unused modules have been imported Function is missing arguments in various calls The appropriate format indentation is missing Missing appropriate spaces before and after […]