Articolo originale: JavaScript Optional Chaining `?.` Explained - How it Works and When to Use it

Cos'è l'optional chaining?

L'optional chaining (concatenamento opzionale), rappresentato da ?. in JavaScript, è una nuova funzionalità introdotta con ES2020.

L'optional chaining cambia la maniera in cui accedere alle proprietà in oggetti annidati in profondità. Risolve il problema di dover fare molteplici controlli per valori nulli quando si accede a una lunga catena di proprietà in JavaScript.

Stato attuale: stadio 4 del processo di approvazione ECMAScript: https://github.com/tc39/proposal-optional-chaining

Casi d'uso

  1. Accedere alle proprietà di un oggetto con valore potenzialmente  null o undefined.
  2. Ottenere risultati da una variabile che potrebbe non essere ancora disponibile.
  3. Ottenere valori di default.
  4. Accedere a lunghe catene di proprietà.

Immagina che come risposta di una API ti aspetti un oggetto di questo tipo:

obj = {
  prop1: {
    prop2: {
      someProp: "value"
    }
  }
};

Ma potresti non sapere in anticipo se ognuno di questi campi è disponibile. Alcuni potrebbe non essere inclusi nella risposta dell'API, o potrebbero contenere valori nulli.

Per esempio:

//risposta attesa
obj = {
  id: 9216,
  children: [
    { id: 123, children: null },
    { id: 124, children: [{ id: 1233, children: null }] }
  ]
};

//risposta ottenuta
obj = {
  id: 9216,
  children: null
};

Questo succede spesso con funzioni che accedono a una API. Forse ti è capitato di vedere del codice di React che cerca di salvaguardarsi da questo tipo di problema nella seguente maniera:

render = () => {
  const obj = {
    prop1: {
      prop2: {
        someProp: "value",
      },
    },
  };

  return (
    <div>
      {obj && obj.prop1 && obj.prop1.prop2 && obj.prop1.prop2.someProp && (
        <div>{obj.prop1.prop2.someProp}</div>
      )}
    </div>
  );
};

In passato, per prepararsi ad affrontare questo problema, abbiamo spesso usato Lodash, e più precisamente il metodo _.get:

_.get(obj, prop1.prop2.someProp);

Questo metodo ritorna undefined se una qualunque di quelle proprietà è undefined. L'optional chaining è esattamente questo! Adesso invece di usare una libreria esterna, questa funzionalità è integrata.

Come funziona l'optional chaining?

?. può essere usato per concatenare proprietà che potrebbero avere un valore null o undefined.

const propNeeded = obj?.prop1?.prop2?.someProp;

Se una qualsiasi di queste proprietà contenesse un valore null o undefined, JavaScript ritornerebbe undefined.

E se invece volessimo restituire qualcosa di significativo? Puoi provare così:

let alberoGenealogico = {
    noi: {
        figli: {}
    }
}


// con il metodo _.get
const nipoti = _.get(alberoGenealogico, 'noi.figli.loroFigli', 'non hanno avuto figli' );

//con optional chaining e null coalescing 
const nullCoalescing = alberoGenealogico?.noi?.figli?.loroFigli ?? 'non hanno avuto figli'
console.log(nullCoalescing) //non hanno avuto figli

Funziona anche con oggetti che potrebbero essere null o undefined:

let user;
console.log(user?.id) // undefined

Come ottenere questa nuova funzionalità

  1. Provala nella console del tuo browser: essendo un'aggiunta recente, un browser risalente potrebbe necessitare di polyfill. Puoi provarlo nella console di browser come Chrome o Firefox. Se non funzionasse ancora, puoi provare ad abilitare le funzionalità sperimentali di JavaScript visitando chrome://flags/ e abilitando "Experimental JavaScript".
  2. Puoi provarlo nella tua app di Node usando Babel:
{
  "plugins": ["@babel/plugin-proposal-optional-chaining"]
}

Risorse

ttps://dmitripavlutin.com/javascript-optional-chaining/

  1. Documentazione di Babel: https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining

TL;DR

Usa optional chaining ?. con oggetti o lunghe concatenazioni di proprietà che potrebbero contenere un valore null o undefined. La sintassi è la seguente:

let user = {};
console.log(user?.id?.name)