It was born

With the advance of the separation of the front and back end now faster and faster, now the daily development of the front end is often their own do not need to go to the database operation data, only need to call the API can be data acquisition. Although this greatly facilitates our development, it will also be accompanied by a variety of new problems, such as data hierarchy nested too deep, data is not single and a series of reasons, so that we often need to make a lot of logical judgments.

For example, if we take out the data of people on the back end and want to directly obtain its family population, if we get it directly like this, we may sometimes be able to get it, sometimes because the scene changes will be missing this field, and get an ERROR medallion!

const people = {} // Assume this is back-end data

console.log(people.family.numbers);
Copy the code

If you retrieve data that does not exist, you will raise an exception, causing the entire process to be done. However, if a small amount of data does not cause the whole process to be done, it is obviously not what you want, so we need to control it. Here the solution is roughly divided into two kinds, one is the use of third-party libraries, the second said their own manual interception.

  • Third-party libraries

    In this case, we’re going to use lodash directly, and lodash, we’re going to get data from an object, usually using a getter method

        _.get('people'.'family.numbers')
    Copy the code

    If there is a key in lodash, we will return the value of that key, which is the number we want. If there is no key, we will return null (by the way, let’s see what’s going on behind it).

    //get.js
    function _get(data,f){
       if(f.substr) f = f.split(/ \ | \ \ | \ / /);
       if(f.length && data){
           return _get(data[f.shift()],f)
       }else if(! f.length && data){return data
       }else {
           return ""; }}export default function(target,path,defaultValue){
       return _get(target,path,defaultValue);
    }
    Copy the code
  • Native own JS handwriting

    Their own handwriting to intercept the idea is also extremely simple, is to judge whether there is a layer down on the line.

        console.log(people && people.family && people.family.numbers);
    Copy the code

    When making a case-by-case judgment, undefined is returned to avoid an ERROR, but writing it yourself can be extremely complicated if you don’t rely on a third-party library. Suppose the data structure is not three layers deep, but five. What about ten? Doesn’t that make it incredibly complicated?

This is in the context of our pig’s foot today — optional operators, right? .came out! So what do we do with the optional operators?

We just need to use it where we need to judge!

    console.log(people? .family? .numbers);// undefined
Copy the code

It’s that simple!! This is so rude!! Just put one more in front of the judgment, right? Is the

Are you sure you don’t want to learn such a practical operation?

Based on using

Official definition MDN document: Optional chain operator (? .) allows the value of properties deep in the chain of connected objects to be read without explicitly verifying that each reference in the chain is valid. ? The. Operator functions like the.chain operator, except that it does not cause an error if the reference is nullish (null or undefined), and the expression short-circuited to the return value is undefined. When used with a function call, undefined is returned if the given function does not exist.

The optional chain operator will make the expression shorter and more concise when trying to access object properties that may not exist. The optional chain operator is also helpful when exploring the contents of an object where it is not certain which properties must exist.

The basic use of the optional operators is extremely simple, just adding them where an error might be caused by a lack of fields. How do you know where to start raising this error?

Let’s start with the interesting back-end data

const people = {} // Assume this is back-end data

console.log(people); / / {}
console.log(people.family); // undefined
console.log(people.family.number); // ERROR
Copy the code

As can be seen from the output, js itself still has a certain fault tolerance mechanism, so we only need to trigger fault tolerance mechanism in the place, can be added!

While using optional operators is simple, there are a number of caveats

  1. Variables before optional operators must be declared! If the variable preceding the operator is not declared, an error is raised

  2. Don’t overdo it, we only need to use it where we might raise an error,? Although good, don’t take on too much (official advice, why I don’t know)

  3. It ends when null or undefined is encountered.

  4. Optional chain cannot be used for assignment. It can only be used to determine if the key is short-circuited. If it is short-circuited, undefined is returned; otherwise, the value of the key is returned.

Its sibling, the null-value merge operator,

As mentioned above, the optional operator is not allowed to assign values, but its cousin 😎 is. After all, if a calabash can breathe water, it can’t breathe fire

In the past

Before the optional and null-merge operators appear, we need to determine whether a property exists, take its value if it exists, and assign a default value if it doesn’t. We might write a long list like this:

    console.log(people && people.family && people.family.numbers || 'Nonexistent');
Copy the code

It was often extremely long and troublesome, but that’s not the case anymore!

now

We just need to use the two brothers together:

    console.log(people.family? .number ??'Nonexistent');
Copy the code

Only if the front face is null or undefined, the null merge operation will be performed, which is to assign the default value set later.

The advanced

In front of so many, are very basic usage, let’s learn the SAO operation together!

In JS, there are many, many things that can be contained in an object, so? And not just for simple judgements. It can also be applied to arrays, functions, and a range of other operations

Grammar:

obj? .prop obj? .[expr] arr? .[index] func? .(args)Copy the code

Now that we’re done with the first two simple ones, let’s look at arrays and functions.

An array of

In fact, arr? Arr [index] = arR [index] = arr[index] As follows:

let arr = [1, 2, 3]; console.log(arr? . [5]); // undefinedCopy the code

You may think this is a little childish, even if you don’t have to ask, but what if this is the case?

let demo = { } console.log(demo.a[1]); // ERROR console.log(demo.a? . [1]); // undefinedCopy the code

Wouldn’t it be an error if you didn’t make a judgment? Judgment then it’s going to be a tedious series of judgements as in the beginning, but using? .Can’t we solve this problem very quickly?

function

Sometimes we may get some API, but if there is no CORRESPONDING API, the exception will still be thrown. In this case, there is also a solution!

const demo1 = {
    func() {
        console.log('Hey, don't say anything wrong! '); }}const demo2 = {

}

demo1.func(); // Hey!
demo2.func(); // TypeError: demo2.func is not a function
Copy the code

We can perfectly avoid this error by using the optional operator

Const demo1 = {func() {console.log(' hihihi! '); } } const demo2 = { } demo1.func? . (); // Hey! demo2.func? . (); //Copy the code

However, there is an important point to note here. An exception will be thrown when a non-functional property with the same name as the function is identified

Const demo1 = {func() {console.log(' hihihi! '); } } const demo2 = { func = 'demo' } demo2.func? . (); //Copy the code

Many friends will feel uncomfortable in the application of array and function, but you combined with the implementation mechanism of JS to understand, you will understand why to write this and why there is a non-function with the same name will report an error

support

In fact? The.operator is not unique to js. It is currently available in C#, Swift, and TS as well. Node.js requires an upgrade above 14.0 to support it (but Babel is usually used for translation, so don’t worry!).

Browser Support

I am river, front end intern one, article if there is wrong, please be corrected!

In the face of new things, we must have the courage to embrace, only by constantly accepting new things, new characteristics for us to use, in order to keep moving forward, constantly beyond!