Elvis Operator: dá pra usar com JavaScript?

Elvis Operator: dá pra usar com JavaScript?
Júlio César Brito da Silva
Júlio César Brito da Silva

Compartilhe

Nesse artigo, vamos entender o que é o Elvis Operator e como implementá-lo em JavaScript.

Elvis Presley #inset

Quando você está desenvolvendo um objeto com estrutura aninhada no JavaScript, ou seja, objetos dentro de objetos, existe o risco de acessar uma referência que não existe, pois nesta linguagem é difícil de garantir a consistência dos dados de um objeto. É aí que entra o Elvis Operator.

Cannot read property... - não é possível ler a propriedade de...

Imagina que você tem que desenvolver uma aplicação que percorra uma lista de objetos de tarefas. O objeto tarefa teria a estrutura abaixo:

const tarefa = {
    nome: 'Nome da tarefa',
    descricao: 'Descrição da tarefa'
}
const listaDeTarefas = [tarefa];

Em algumas tarefas, a propriedade responsavel ainda não está definida ou pode estar definida com seu valor null (nulo). Agora, imprima no console os valores das propriedades para saber se está tudo funcionando corretamente:

listaDeTarefas.forEach( tarefa => {
    console.log(`
    Nome: ${tarefa.nome}
    Descrição: ${tarefa.descricao}
    `);
});

E, no console, será exibido este resultado:

imagem do console exibindo o resultado da instrução de código que tem como resultado a impressão no console das propriedades nome e descrição do objeto tarefa #inset

Uma vez que a estrutura do objeto tarefa esteja pronta, vamos imprimir em tela o nome do responsável pela tarefa. Para isso, teremos:

listaDeTarefas.forEach( tarefa => {
    console.log(`
    Nome: ${tarefa.nome}
    Descrição: ${tarefa.descricao}
    Responsável: ${tarefa.responsavel.nome}
    `)
});

E, no console, o resultado é:

imagem do console exibindo o resultado da instrução de código que tem como objeto a impressão no console das propriedade nome, descrição (do objeto tarefa) e o nome do responsável do objeto responsável. Ocorre um erro: não é possível ler a propriedade nome porque ela não foi definida #inset

Temos um erro. O erro do undefined acontece porque a propriedade responsavel não está definida no objeto tarefa. E se nosso objeto tarefa tivesse a propriedade responsavel definida como valor null, um erro similar aconteceria, veja a seguir:

const tarefa = {
    nome: 'Nome da tarefa',
    descricao: 'Descrição da tarefa',
    responsavel: null
}

E no console:

imagem do console exibindo o resultado da instrução de código que tem como objeto a impressão no console das propriedade nome, descrição (do objeto tarefa) e o nome do responsável do objeto responsável. Ocorre um erro: não é possível ler a propriedade nome porque ela foi definida como null (nulo) #inset

O erro desta vez acontece, pois a propriedade responsavel foi definida, porém está com o valor null.

Banner de divulgação da Imersão IA da Alura em colaboração com o Google. Mergulhe em Inteligência artificial com a Alura e o Google. Serão cinco aulas gratuitas para você aprender a usar IA na prática e desenvolver habilidades essenciais para o mercado de trabalho. Inscreva-se gratuitamente agora!

Operador Ternário no JavaScript

Este é um erro bastante recorrente quando estamos percorrendo uma lista de objetos aninhados (encadeados), pois pode acontecer de alguma dessas propriedades que estão sendo utilizadas ainda não estarem definidas ou serem estabelecidas como null. Para que possamos solucionar o problema, vamos fazer da seguinte forma:

listaDeTarefas.forEach( tarefa => {
    console.log(`
    Nome: ${tarefa.nome}
    Descrição: ${tarefa.descricao}
    Responsável: 
      ${
        (tarefa.responsavel) ?
        tarefa.responsavel.nome : 
        ''
      }
    `)
});

E, no console, teremos este resultado:

imagem do console exibindo o resultado da instrução de código que tem como instrução uma condição ternária: se a objeto `responsavel` que está dentro do objeto tarefa for diferente de null (nulo), então, imprime na tela a propriedade nome do objeto responsável. Se não, imprime uma string vazia, que é o que acontece na imagem acima #inset

Perceba que no console uma string vazia foi exibida para o nome do responsável, pois o que fizemos em nosso código foi usar o operador de condicional ternário. Ou seja, se **tarefa.responsavel** for definida e com valor diferente de null, então imprime no console o nome do responsável pela tarefa através da referência **tarefa.responsavel.nome**, enquanto que, se o nome do responsável for null, então imprime a string vazia, evitando que um erro aconteça.

Optional Chaining

Seria muito cansativo fazer a verificação se cada propriedade de um objeto foi definida ou não utilizando o operador ternário. Para este caso, teríamos que escrever muito código. Portanto, o JavaScript tem um operador para nos poupar de escrever tanto código:

listaDeTarefas.forEach( tarefa => {
  console.log(`
  Nome: ${tarefa.nome}
  Descrição: ${tarefa.descricao}
  Responsável: ${tarefa.responsavel?.nome}
    `)
});

E, no console, teríamos:

imagem do console exibindo o resultado da instrução de código que tem como instrução uma condição ternária: se a objeto `responsavel` que está dentro do objeto tarefa for diferente de null (nulo), então, imprime na tela a propriedade nome do objeto responsável. Se não, imprime uma string vazia, que é o que acontece na imagem acima #inset

Então, perceba que nesse trecho de código tarefa.responsavel?.nome utilizamos o ?, operador opcional de encadeamento. O JavaScript possui esta estrutura condicional que permite o acesso às propriedades dentro de objetos encadeados.

O optional chaining, que chegou no JavaScript em 2020, é uma sugar syntax (uma forma mais simples de escrever um código mais complexo) e um operador binário, que oferece uma maneira de fazer uma navegação segura entre os objetos.

Operador de coalescência nula

No JavaScript, o mais próximo ao conhecido “Elvis Operator” (?:) de outras linguagens é o operador de coalescência nula, que aqui tem a notação de dois símbolos de interrogação: ??.

O equivalente ao “Elvis Operator” retorna os resultados caso o seu primeiro operando for um valor verdadeiro. Caso contrário, ele retorna o segundo operando, portanto pode ser usado para definir uma mensagem padrão caso a propriedade do objeto esteja nula ou não definida:

listaDeTarefas.forEach( tarefa => {
  console.log(`
  Nome: ${tarefa.nome}
  Descrição: ${tarefa.descricao}
  Responsável: ${tarefa.responsavel?.nome ?? ‘Sem responsável’}
    `)
});

De acordo com o site “Can I Use?”, este operador já tem suporte para os browsers mais modernos.

Você deve estar se perguntando porque ele é chamado de O Elvis? O nome Elvis Operator foi dado porque sua notação em outras linguagens se dá por “?:”, ao olhá-lo de lado, se assemelha ao emoji do Elvis Presley com seu topete.

Quer saber mais sobre o JavaScript? Aqui na Alura, temos a Escola JavaScript. Front End, onde nos aprofundamos ainda mais sobre o ecossistema da linguagem. Te vejo numa próxima, até mais!

Júlio César Brito da Silva
Júlio César Brito da Silva

Apaixonado por educação e tecnologia, atuo como instrutor e desenvolvedor na Escola Front End aqui na Alura.

Veja outros artigos sobre Front-end