简体   繁体   中英

What does the ?. syntax mean in JavaScript?

I came across this C# like code in a React project. I couldn't confirm if this syntax correct or not. I didn't find any recent ES version release to support this syntax. In current scenario I'm not authorized to execute and check this code.

I tried testing this syntax in browse console and encountered error:

{cart?.widgets?.items.map(widget => (
        <div className="billing-details__box" key={widget.id}>
          <p className="m-0">{widget.name}</p>
          <p className="my-0">{widget.value} $</p>
        </div>
 ))}

My concern with above code is whether cart?.widgets?.items will raise any error or not.

It is optional chaining which is JS new feature.

Basically it is the same as:

{cart && cart.widgets && cart.widgets.items.map(widget => (
        <div className="billing-details__box" key={widget.id}>
          <p className="m-0">{widget.name}</p>
          <p className="my-0">{widget.value} $</p>
        </div>
 ))}

For more details be sure to visit V8 guide .

I couldn't confirm if this syntax correct or not.

It is correct TypeScript code, and is correct JavaScript depending on what engine you're running it in. Chrome (V8) supports this syntax already (see caniuse.com ).

Here you can read more about the proposal to add this syntax to a future JS spec.

What is it?

This syntax is called the optional chaining operator , and it allows you to access properties that may or may not exist on an object without having to check for the properties existence no matter how deep the property access expression is .

For example, say we have some object like so:

const user = {
  details: {
    name: "SpongeBob SquarePants"
  },
  repo: null
};

And we want to get their name and, if it exists, some property user.repo.url . We can use the optional chaining operator to get both without having to worry whether repo is an object or not:

console.log(user.details.name) //=> "SpongeBob SquarePants"
console.log(user.repo.url) //=> undefined

It also works for function calls. For example, say when user.repo has a value we know it will be a function that returns a string. However, sometimes, as above, it may not be a function. We can do the following to call the function if it exists, but the code will not throw an error if the value at user.repo.url is not a function:

console.log(user.repo?.url()) //=> undefined

Without optional chaining operator?

You can achieve the similar behaviour to the optional chaining operator by explicitly checking the truthiness of each object property in the chain of properties that you are accessing.

This can be done either by taking advantage of JavaScript's short-circuit evaluation behaviour, or more obviously with the ternary operator .

It would look something like this:

 function getItems_shortCircuit(obj) { return obj && obj.widgets && obj.widgets.items } function getItems_ternary(obj) { return obj ? obj.widgets ? obj.widgets.items ? obj.widgets.items : null : null : null } let cart = { widgets: null } console.log(getItems_shortCircuit(cart)) //=> null cart.widgets = { items: ["a", "b"] } console.log(getItems_ternary(cart)) //=> ["a", "b"]

My concern with above code is whether cart?.widgets?.items will raise any error or not.

It depends on whether the project is using TypeScript, which supports optional chaining ( ?. ) out-of-the-box. You can read about it in the TypeScript documentation .

If you are not using TypeScript then you must compile your application using some ESNext compiler such as Babel, which has the @babel/plugin-proposal-optional-chaining plugin .

It will be compiled by Babel and it will work. https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining

It's Optional Chaining and it should not cause any error if you use polyfills. "?." - is not supported by default yet

这可能是 Typescript 的可选链接

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM