1.1.6 Expressões Condicionais e Predicados
O poder expressivo da classe de funções que podemos definir neste ponto é muito limitado, porque não temos como fazer testes e realizar diferentes operações dependendo do resultado de um teste. Por exemplo, não podemos declarar uma função que calcula o valor absoluto de um número testando se o número é não-negativo e tomando diferentes ações em cada caso de acordo com a regra:
Esse construto é uma análise de caso e pode ser escrito em JavaScript usando uma expressão condicional como:1
que poderia ser expresso em português como "Se x é maior ou igual a zero, retorne x; caso contrário, retorne -x."
A forma geral de uma expressão condicional é:
predicado ? expressão-consequente : expressão-alternativa
Expressões condicionais começam com um predicado - ou seja, uma expressão cujo valor é true ou false, dois valores booleanos distintos em JavaScript. Os expressões booleanas primitivas true e false avaliam trivialmente para os valores booleanos verdadeiro e falso, respectivamente. O predicado é seguido por um ponto de interrogação, a expressão-consequente, dois-pontos e, finalmente, a expressão-alternativa.
Para avaliar uma expressão condicional, o interpretador começa avaliando o predicado da expressão. Se o predicado é avaliado como verdadeiro, o interpretador avalia a expressão-consequente e retorna seu valor como o valor da condicional. Se o predicado é avaliado como falso, ele avalia a expressão-alternativa e retorna seu valor como o valor da condicional.
A palavra predicado é usada para operadores e funções que retornam verdadeiro ou falso, bem como para expressões que avaliam para verdadeiro ou falso. A função de valor absoluto abs faz uso do predicado primitivo >=, um operador que recebe dois números como argumentos e testa se o primeiro número é maior ou igual ao segundo número, retornando verdadeiro ou falso de acordo.
Se preferirmos lidar com o caso zero separadamente, podemos especificar a função que calcula o valor absoluto de um número escrevendo:
Em JavaScript, expressamos uma análise de caso com múltiplos casos aninhando expressões condicionais como expressões alternativas dentro de outras expressões condicionais:
Parênteses não são necessários ao redor da expressão alternativa x === 0 ? 0 : - x, porque a forma sintática da expressão condicional é associativa à direita. O interpretador ignora espaços e quebras de linha, aqui inseridos para legibilidade para alinhar os ? e : sob o primeiro predicado da análise de caso.
A forma geral de uma análise de caso é:
p₁
? e₁
: p₂
? e₂
...
: pₙ
? eₙ
: expressão-alternativa-final
Chamamos um predicado pᵢ junto com sua expressão consequente eᵢ de uma cláusula. Uma análise de caso pode ser vista como uma sequência de cláusulas, seguida por uma expressão alternativa final.
De acordo com a avaliação de expressões condicionais, uma análise de caso é avaliada primeiro avaliando o predicado p₁. Se seu valor for falso, então p₂ é avaliado. Se o valor de p₂ também for falso, então p₃ é avaliado. Este processo continua até que um predicado seja encontrado cujo valor seja verdadeiro, caso em que o interpretador retorna o valor da expressão consequente correspondente da cláusula como o valor da análise de caso. Se nenhum dos p for encontrado como verdadeiro, o valor da análise de caso é o valor da expressão alternativa final.
Operadores Lógicos
Além de predicados primitivos como >=, >, <, <=, === e !== que são aplicados a números, existem operações de composição lógica, que nos permitem construir predicados compostos. Os três mais frequentemente usados são:
-
Conjunção Lógica: expressão₁
&&expressão₂Esta operação expressa conjunção lógica, significando aproximadamente o mesmo que a palavra em português "e". Assumimos que esta forma sintática é açúcar sintático para:
expressão₁
?expressão₂:false -
Disjunção Lógica: expressão₁
||expressão₂Esta operação expressa disjunção lógica, significando aproximadamente o mesmo que a palavra em português "ou". Assumimos que esta forma sintática é açúcar sintático para:
expressão₁
?true:expressão₂ -
Negação Lógica:
!expressãoEsta operação expressa negação lógica, significando aproximadamente o mesmo que a palavra em português "não". O valor da expressão é verdadeiro quando a expressão é avaliada como falso, e falso quando a expressão é avaliada como verdadeiro.
Observe que && e || são formas sintáticas, não operadores; sua expressão do lado direito nem sempre é avaliada. O operador !, por outro lado, segue a regra de avaliação da seção 1.1.3. É um operador unário, o que significa que recebe apenas um argumento, enquanto os operadores aritméticos e predicados primitivos discutidos até agora são binários, recebendo dois argumentos. O operador ! precede seu argumento; nós o chamamos de operador prefixo. Outro operador prefixo é o operador de negação numérica, um exemplo do qual é a expressão - x nas funções abs acima.
Como exemplo de como esses predicados são usados, a condição de que um número x esteja no intervalo 5 < x < 10 pode ser expressa como:
x > 5 && x < 10
A forma sintática && tem precedência mais baixa que os operadores de comparação > e <, e a forma sintática de expressão condicional tem precedência mais baixa que qualquer outro operador que encontramos até agora, uma propriedade que usamos nas funções abs acima.
Como outro exemplo, podemos declarar um predicado para testar se um número é maior ou igual a outro como:
ou alternativamente como:
A função maior_ou_igual, quando aplicada a dois números, se comporta da mesma forma que o operador >=. Operadores unários têm precedência mais alta que operadores binários, o que torna os parênteses neste exemplo necessários.