Short-Circuit Evaluations e Logical Assigning Operators: Como são usados?

Short-Circuit Evaluations e Logical Assigning Operators: Como são usados?

Ainda no começo da jornada de aprendizado de JavaScript, aprendemos a utilizar estruturas de controle utilizando blocos de if/else. Todavia, no decorrer da carreira, nos deparamos com estruturas não tão intuitivas, mas que proporcionam um código mais limpo e elegante, como short-circuit evaluations e logical assigning operators. Este texto visa auxiliar novos desenvolvedores que desejam compreender o funcionamento destas estruturas.

Truthy and Falsy values

Antes de falar sobre as estruturas em si, é essencial esclarecer o que são truthy and falsy values. Se você já domina este conteúdo, pode pular este bloco.

Em JavaScript, qualquer tipo de dado pode ser convertido em valor booleano. Essa conversão ocorre, por exemplo, quando utilizamos estruturas de controle. Zero (0 ou -0), string vazia (“”), NaN (Not a Number), null e undefined são convertidos para false, por isto, são denominados falsy values. Todos os demais valores são convertidos para true e, portanto, chamados de truthy values.

No Ex. 1, será impressa no console a string “Condição não atendida”, pois a constante "stringVazia" será convertida no valor booleano false, fazendo com que o bloco else seja executado. Por outro lado, no Ex. 2, a string “false”  (não confundir com o valor booleano false), é um valor diferente de 0, -0, “”, NaN, null e undefined, sendo, portanto, um valor truthy. Como tal, será convertido para true, motivo pelo qual a string “Condição atendida” será impressa no console.

Operadores Lógicos OR e AND

Os operadores lógicos OR (||) e AND (&&) são utilizados para realizar cálculos de álgebra booleana. Este tipo de cálculo consiste em encadear valores booleanos, e, ao final, apurar se o resultado desse encadeamento será verdadeiro ou falso. Quando utilizamos o operador “or” o resultado do encadeamento será falso apenas se todos os operandos forem falsos e, no caso do operador “and”, o resultado será verdadeiro apenas se todos os operandos forem verdadeiros.

Imagine, por exemplo, que precisamos escolher um estado brasileiro cujo nome comece com a letra P ou que se situe na região nordeste do país. Para isto, dispomos do array nordeste:

Podemos verificar o resultado das afirmações isoladamente da seguinte forma:

Verificamos que a primeira hipótese é verdadeira e a segunda falsa. Para verificar se “Paraná” atende às especificações, faremos o seguinte:

Conforme esperado, o resultado é verdadeiro, pois uma das afirmações é verdadeira. Note que nem é necessário verificar se “Paraná” está contido no array nordeste, pois, independentemente da resposta, o resultado final da expressão será verdadeiro. Considere que agora que as especificações são que o estado escolhido precisa ter um nome iniciado com a letra P e estar situado na região nordeste. Esta verificação poderia ser realizada da seguinte forma:

A resposta da expressão é falsa porque existe pelo menos uma afirmação falsa no encadeamento. Ao contrário da expressão anterior, mesmo a primeira afirmação sendo verdadeira, é necessário verificar se a segunda também é para saber se o resultado da expressão lógica é verdadeiro ou falso.

O comportamento de interromper as avaliações dos operandos de uma expressão lógica quando já é possível determinar o resultado da expressão antes de avaliar todos os operandos pode ser utilizado para executar código condicionalmente. Esta técnica é conhecida como short-circuit evaluations e pode ser resumida com a tabela abaixo:

OR

Retorna o primeiro valor truthy da cadeia, sem avaliar os demais. 

AND

Retorna o primeiro valor falsy da cadeia, sem avaliar os demais.  

Em ambos os casos, se o valor procurado não for encontrado no encadeamento, o último valor da cadeia será retornado.

OR Short-Circuit ||


Para ajudar na explicação do funcionamento do “or” short-circuit, imagine o seguinte cenário:

  1. Dispondo de um array de heróis e heroínas, sua tarefa consiste em criar um novo array composto pela propriedade avatar de cada  herói;
  2. A propriedade avatar possui uma string que poderá ser utilizada numa requisição HTTP para mostrar fotos únicas destes heróis e heroínas. Contudo, por uma falha qualquer, a propriedade avatar de alguns dos objetos estão com valores null ou “”;
  3. Nestes casos, sua orientação é incluir no novo array a string “/fotoPadrão.png”.

O problema poderia ser resolvido dessa forma:

A arrow function passada como parâmetro para o método map do array "herois” retornará o valor de heroi.avatar, se este for truthy. Se for falsy, a arrow function retornará a string “/fotoPadrão.png”. Contudo, o mesmo problema poderia ser resolvido assim:

Nesta segunda alternativa, se a propriedade do objeto heroi.avatar for truthy, o valor de heroi.avatar será retornado pela arrow function e o conteúdo após o operador || será ignorado. Se o valor de heroi.avatar for falsy, a string “fotoPadrao.png” será retornada.

OR Assigning Operator ||=


Atribui um valor a uma variável qualquer caso o valor contido nesta variável seja falsy. Se nosso objetivo fosse atribuir à propriedade heroi.avatar o valor “/fotoPadrão.png” nos objetos em que esta propriedade não está apropriadamente definida, poderíamos fazê-lo da seguinte forma:

Utilizando OR short-circuiting, poderíamos solucionar o problema da seguinte forma:


Ao iterar pelo array herois, se for constatado que o valor de heroi.avatar é truthy, o código escrito após o operador lógico || será ignorado. Caso contrário, o valor “/fotoPadrao.png” será atribuído à propriedade heroi.avatar. Este comando pode ser escrito de forma simplificada, fazendo uso do OR assignment operator, utilizando a sintaxe abaixo:

Como se observa, o OR assignment operator serve para atribuir valores condicionalmente à variáveis ou propriedades que possuem valores falsy.

Nullish Short Circuiting ??

Imagine agora o seguinte cenário:

  1. Você dispõe de um array com estatísticas de partidas de um campeonato de futebol e precisa criar um novo array com o número de cartões recebidos em cada jogo;
  2. Em alguns elementos do array, a informação a respeito do número de cartões não está disponível;
  3. Nestes casos, a orientação é incluir a string “não informado” em substituição ao número de cartões recebidos naquele jogo.

Aplicando OR short-circuit evaluation, obtemos a seguinte solução:

Perceba que apesar de nenhum jogador ter recebido cartões no jogo entre Alemanha e Holanda, a string ‘Não informado’ foi incluída no array no índice correspondente. Isso acontece porque o número zero é um valor falsy. Poderíamos resolver este bug da seguinte forma:

No entanto, o mesmo resultado pode ser obtido aplicando o Nullish Short Circuiting Operator, representado por ??. Este operador funciona de forma similar ao “or” Short Circuiting operator, com a diferença que retorna o primeiro valor diferente de “null ou “undefined”.

Nullish Assigning operator ??=

Para atribuir o valor padrão “Não Informado” apenas aos objetos em que o valor da propriedade é null ou undefined, podemos utilizar o Nullish Assignment Operator.

Esta sintaxe equivale a

AND Short-Circuit &&

Imagine que a cada cartão sofrido, a seleção deverá pagar uma multa de R$ 100,00. O valor total devido pelos times a título de multa precisa ser impresso no console. Para resolver este problema, é necessário multiplicar o número de cartões por 100 apenas nos jogos em que o número de cartões está definido. Desconsiderando as alterações realizadas no objeto jogos nos Ex. 11 e 12, poderíamos resolver o problema da seguinte forma:

O mesmo problema poderia ser resolvido utilizando a seguinte sintaxe:

AND assignment operator &&=

Ao contrário do OR assignment operador que atribui valor a variável que contenha valores falsy, o AND assignment operator atribui valor a variáveis que contenham valores truthy. Podemos aproveitar esta ferramenta e refatorar a constante multa para torná-la uma função que retorna uma string formatada.

Neste exemplo, a função calcularMulta recebe o array de jogos e calcula o valor total da multa. Se este resultado for truthy, o valor da variável multa é sobrescrevido com a string formatada e, por fim, o novo valor da variável multa será retornado. Caso contrário, será retornada a string “Verifique os dados.”. Por fim, ressaltamos que as linhas de código abaixo são equivalentes:

Vale ressaltar que os logical assigning operators foram introduzidos  recentemente no JavaScript, portanto, é importante consultar a documentação para conferir se esta sintaxe é compatível com a versão do Node ou do Browser em uso.

Em resumo…

Neste artigo falamos sobre valores truthy e valores falsy e a importância deles quando escrevemos estruturas de controle. Falamos, também, sobre short-circuit evaluations e logical assignment operators e sobre como podem ser utilizados para substituir estruturas de controle compostas pelos tradicionais blocos de if/else.

Para aprofundar o conteúdo, vale a pena consultar o livro JavaScript: O Guia Definitivo, do David Flanagan, e a MDN web docs, que serviram como referências para este texto. Muito obrigado por sua atenção e, caso tenha dúvidas ou sugestões, não deixe de me contatar nas redes sociais.

⚠️
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.