preface

Believe that most of the development of the front-end code farmers will encounter a problem, in a deep traversal tree structure of the data, the total is going to judge the existence of the intermediate node data and then go to the values or the corresponding operation, the most common scenario is in the docking the backend API, suppose now have so a API returns obj.

let person = {
    name: 'a',
    owner: {
        token: '54163sdf',
        permission: {
            usecar: true}}},let usecar = person.owner.permission.usecar()
Copy the code

We need to get the permission under the owner of person and the permission under the car usecar. The above code is what we do most of the time. The problem is, how can we ensure that the data of the middle node of the object exists?

Conventional way

Most of the time what we do is we judge values or we introduce three-party libraries like LoDash and so on

if (person && person.owner && person.owner.permission) {
    let usecar = person.owner.permission.usecar, 
}
_.get(person, 'owner.permission.usecar');
Copy the code

The above method can also solve the corresponding problem, but it is not the problem discussed in this article. The focus is on the following.

Arises at the historic moment

Optionalchaining, in this context, is currently in the draft stage2 stage and will soon be used in large scale. It allows us to check if an attribute on an object is null or undefined, and return undefined if it is.

// An exampleletusecar = person? .owner? .permission? .usecar ??true;
Copy the code

Isn’t it cool that you don’t have to write too much duplicate code for fault tolerance, but just to explain how it works, operator checking? . Checks whether the value to the left of the operator is null or undefined. If so, the expression terminates and returns undefined. Otherwise, the expression continues to check through! In addition, Nullish coalescing operator (?? Operator), we can easily handle situations like default values.

grammar

// The Optional Chaining syntax is used in three scenarios: obj? .prop // optional static property access obj? .[expr] // optional dynamic property access func? . (... args) // optionalfunction or method call

Copy the code

As for why syntax is not OBj? Prop, a more concise expression, is mentioned in the FAQ as an example:

obj? [expr]. Filter (fun):0 obJ? [expr] is Optional Chaning, or this is a common ternary operation statement.

For a detailed analysis of this proposal, the following article is recommended: Analysis of Optional Chaining

Use of

Because it’s still a proposal and the browser doesn’t support it well, it’s not possible to use it in the project, but someone quietly helped us pave the way. The Babel plug-in already exists. Babel-plugin-proposal-optional-chaining, this plug-in is used for elocaining the rapture.

const babel = require('@babel/core');

const code = 'const obj = {}; const baz = obj? .foo? .foo1';

const output = babel.transformSync(code, {
  plugins: ["@babel/plugin-proposal-optional-chaining"]}); console.log(output.code);Copy the code

Here is the compiled code:

var _obj$foo;

const obj = {};
const baz = obj === null || obj === void 0 ? void 0 : (_obj$foo = obj.foo) === null || _obj$foo === void 0 ? void 0 : _obj$foo.foo1;
Copy the code

This seems to make sense, but note that the Bebel plug-in does not support Nullish coalescing Operator (?? Operator).