Apesar de todos os aprimoramentos que a linguagem JavaScript adicionou nos últimos anos, como o operador de propagação, valores de argumento padrão e funções de seta, ainda há alguns recursos que eu gostaria de ver implementados. Um desses recursos é o encadeamento opcional. O encadeamento opcional permite que os desenvolvedores façam referência a propriedades de objetos que podem ou não existir sem disparar um erro.

Veja o exemplo a seguir:

const person = {
  name: "David",
  skills: {
    javascript: {
      frameworks: ["MooTools", "React"],
    }
  },
  save: () => { }
};

// Property that *doesn't* exist (css)
person.skills.css.frameworks;
// Uncaught TypeError: Cannot read property 'frameworks' of undefined

A tentativa de obter uma propriedade de um pai indefinido resulta em um TypeError que pode bloquear seu aplicativo. Nesse caso, queremos verificar se o css existe:

if(
  person.skills && 
  person.skills.css && 
  person.skills.css.frameworks) {
    // ...
}

Escrevi um chamado Objectifier para facilitar a referência a propriedades de objetos aninhados, mas com o Proposta de encadeamento opcionalagora temos uma forma nativa.

Um exemplo simples de encadeamento opcional é:

const skills = person?.skills;

O senhor pode continuar o padrão ao longo da linha de objetos aninhados:

const frameworks = person?.skills?.javascript?.frameworks;

Se uma propriedade não existir, o encadeamento será interrompido e o undefined é retornado. O encadeamento opcional também é compatível com a sintaxe de colchetes:

const language = "javascript";
const frameworks = person?.skills?.[language]?.frameworks;

O senhor também pode chamar uma função sem penalidades:

// Calls save if exists, otherwise nothing
const frameworks = person?.save();

O senhor pode até usar a sintaxe de encadeamento no objeto de nível superior:

addEventListener?.("click", e => { });

methodDoesntExist?.(); // undefined

O senhor pode até mesmo usar a desestruturação com encadeamento opcional:

const { frameworks, doesntExist } = person.skills?.javascript;

Se quiser definir um valor de fallback no caso de um valor ser indefinido, o senhor pode fazer isso com ??:

let frameworkz = person?.skills?.["javascript"]?.frameworkz ?? "react.js";

No momento em que escrevo, o encadeamento opcional ainda não aparece em nenhum navegador, mas o senhor pode brincar com o encadeamento opcional no site Compilador on-line Babel.

O encadeamento opcional parece ser uma mudança um tanto controversa. Tem-se argumentado que os desenvolvedores devem conhecer e validar os objetos que estão usando; por outro lado, a verificação contínua de propriedades aninhadas é um pesadelo. Estou ansioso pelo encadeamento opcional em JavaScript. O que o senhor acha?