O Valor dos Tipos de Operadores - Parte 2
Continuando o último capítulo onde falavamos sobre valores, tipos e operadores, veja o que será visto neste capítulo logo abaixo:
- Valores Booleanos
- Valores Truthy e Falsy
- Truques com o Operador
! - Cuidado com a Falsidade!
- Valores undefined
- Operadores Unários
- Operadores de Incremento
- Operadores de Comparação
- Coerção (ou conversão) de Tipo
- Como Evitar a Coerção de Tipo
- Operadores Lógicos
- Curiosidades sobre os Operadores Lógicos
- Operador Ternário
- Regras de Precedência
Valores Booleanos
Esse tipo de dado, boolean, é bem específico, tendo apenas dois valores possíveis, true ou false (verdadeiro ou falso). Conseguimos obter estes valores através de operações de comparação (x é maior que y ? A resposta é sempre sim ou não, verdadeiro ou falso no caso) e através de um “truque” utilizando o operador unário ! (mais sobre operadores unários e comparações adiante).
Este operador ! (negação) inverte o valor passado à ele para um valor booleano oposto ao original. Vou explicar melhor, acompanhe comigo:
Quando aplicamos o operador ! à uma variável que tenha realmente um valor considerável, obtemos o valor false como retorno desta operação. Mas para ficar mais claro o que é um valor considerável, vou te explicar o que é um valor descartável.
Valores Truthy e Falsy
|
Agora você já precisa ter os conceitos de valor, tipo e operador em JavaScript bem consolidados. Faça um exercício mental de definir para você mesmo o que cada um é. |
Todos os tipos de valores em JavaScript têm, intrínsicamente (em sua essência), um respectivo valor booleano associado. Estes valores são claramente perceptíveis quando fazemos comparações entre valores e quando utilizamos o operador unário de negação !.
Valores falsy (falsos) são os que tem em sua essência o valor booleano false. Estes valores são:
false-
0(zero) -
""(string vazia) nullundefinedNaN
Todos os outros valores em JavaScript são considerados truthy (verdadeiros). Alguns valores truthy peculiares são:
-
"0"(zero como string) -
"false"(false como string) -
function() {}(funções vazias) -
[](arrays vazios) -
{}(objetos vazios)
Truques com o Operador !
Agora que sabemos exatamente quais valores booleanos cada valor do JavaScript carrega, podemos tranquilamente e conscientemente utilizar o operador ! para obter o valor contrário do natural do valor em operação. Vamos aos exemplos, e portanto, ao console!:
1 !false // -> true
2 !0 // -> true
3 !"" // -> true
4 !NaN // -> true
5 !"0" // -> false
6 !"false" // -> false
7 !function() {} // -> false
8 !{} // -> false
Um modo interessante de saber qual é o valor truthy ou falsy de um valor é negando-o duas vezes com o operador !. Sim, é como na Matemática, -1 x -1 = 1. Então temos que:
1 !!false // -> false
2 !!NaN // -> false
3 !!{} // -> true
4 !!function() {} // -> true
Cuidado com a Falsidade!
Iremos ver ainda neste capítulo como comparar valores através dos operadores de comparação, mas é importantíssimo que eu lhe explique mais uma última coisa sobre os valores falsy.
As regras de comparação entre estes valores é um pouco não-intuitiva, logo ter o conhecimento dos valores esperados em determinados casos é crucial na hora de um eventual bug. Vamos ver quais são essas peculiaridades.
false, 0 e ""
Quando comparamos dois destes três valores utilizando o operador ==, o resultado é sempre true. Vamos testar no console o código abaixo:
|
OBS: Quando utilizamos o console, podemos omitir o sinal |
1 false == 0 // -> true
2 false == "" // -> true
3 0 == "" // -> true
null e undefined
Os valores null e undefined somente são equivalentes a eles mesmos. Vejamos:
1 null == false // -> false
2 null == null // -> true
3 undefined == false // -> false
4 undefined == undefined // -> true
5 undefined == null // -> true
O último valor falsy que temos para citar é o NaN, porém este já foi abordado no capítulo anterior, e sabemos que é o único tipo de dado em JavaScript que não é igual a ele mesmo.
Valores Undefined
Temos definidos no JavaScript dois tipos indefinidos, usados para representar a falta de representatividade de algum dado.
ps: O paradoxo da frase anterior é apenas uma brincadeira, pois a definição é muito simples, e vou lhe explicar agora! =)
Como já foi explicado no capítulo anterior, na realidade apenas undefined é de fato um tipo primitivo de dado, null é um tipo de objeto, quando fazemos sua inspeção no console podemos verificar isso.
O valor undefined aparece quando declaramos uma variável e não atribuímos a ela nenhum valor. Já o valor null é um valor que deve ser atribuído a uma variável, e representa a ausência de valor nesta variável.
Confira os exemplos no capítulo anterior na seção tipos de dados para fixar esta diferença.
Operadores Unários
Alguns operadores são palavras ao invés de símbolos. Utilizamos um destes operadores muito nos exemplos do capítulo anterior, o operador typeof, que produz uma string identificando o tipo do valor do elemento que você passou a ele.
ps: Para ver o operador typeof em funcionamento, volte no capítulo anterior onde você encontrará vários exemplos da utilização dele.
Outros operadores unários são delete e void. Para este material não se tornar muito extenso, você pode procurar o que cada um faz aqui(delete) e aqui(void).
|
Operadores unários utilizam um valor para fazer seu trabalho, operadores binários e ternários, dois e três valores respectivamente. |
Operadores de Incremento
Temos dois tipos de operadores de incremento: os utilizados para números e os utilizados para strings e números.
Incrementando Números
Os operadores ++ e -- são utilizados para incrementar variáveis/valores do tipo number. São operadores frequentemente utilizados para auxiliar na estrutura lógica do programa, aumentando ou diminuindo em uma unidade o valor da variável. A partir do próximo capítulo iremos começar a focar em pedaços de código maiores, e assim iniciar a criação de mini-programas, para depois chegarmos no nosso objeto de juntar todas essas peças para criarmos o que quisermos. Por agora, vamos ver no console como funcionam estes operadores.
Uma última informação. Estes operadores podem ser utilizados antes ou depois da variável, sendo assim denominados operadores de pré-incremento ou pós-incremento. Qual a diferença entre eles? A diferença é que quando utilizamos o operador antes da variável, ela será alterada antes da execução do código, então o valor processado para a operação atual será o já modificado, e quando usamos o operador depois da variável, essa alteração será percebida apenas depois quando esta variável for solicitada.
Vamos aos testes!
1 var total = 0;
2 total++ // -> 0 (valor foi alterado, mas será percebido na próxima operação)
3 total // -> 1
4 ++total // -> 2
5 --total // -> 1
6 total-- // -> 1
7 total // -> 0
Incrementando Números e Strings
Estes operadores serão utilizados sempre por você! São realmente MUITO importantes e elegantes, diga-se de passagem. A função deles é adicionar mais conteúdo a antiga variável mas sem precisar declarar isso de forma verbosa (escrevendo mais do que se poderia/deveria). De fato, estes operadores operam e atribuem o valor para a mesma variável. Ele pode ser utilizado para somar, subtrair, multiplicar e dividir números, ou para concatenar novas strings em variáveis que contém valores deste tipo.
Vamos dar uma olhada como estes operadores trabalham.
1 // somando números
2 var resultado = 7
3 resultado += 6 // -> 13
4
5 // concatenando strings
6 var meuNome = 'Eric'
7 meuNome += ' Douglas' // -> "Eric Douglas"
8
9 // subtraindo números
10 resultado -= 6 // -> 7
11
12 // multiplicando números
13 resultado *= 3 // -> 21
14
15 // dividindo números
16 resultado /= 2 // -> 10.5
17
18 // resto da divisão de números
19 resultado %= 2 // -> 0.5
20
21 // um exemplo de como somar na mesma variável
22 // sem usar estes operadores
23 resultado = resultado + 0.8 // -> 1.3
Operadores de Comparação
Operadores de comparação são um dos tipos de operadores binários, que no caso, utilizam dois valores para efetuarem a operação. Os operadores de comparação sempre retornam um booleano, dizendo se a comparação é verdadeira ou falsa. São também utilizados na estrutura lógica do programa.
Vamos conhecer estes operadores!
< : menor que - verifica se o número da esquerda é menor que o número/string da direita
<= : menor ou igual que - verifica se o número da esquerda é menor ou igual ao número/string da direita
> : maior que - verifica se o número da esquerda é maior que o número/string da direita
>= : maior ou igual que - verifica se o número da esquerda é maior ou igual ao número/string da direita
Cuidado ao Comparar Strings!
A maneira de comparar strings pode não ser muito intuitiva, pois qualquer letra maiúscula será sempre menor que uma letra minúscula.
Vamos confirmar toda essa teoria agora. Já sabé né? Console! =)
1 13 < 26 // -> true
2
3 'treze' < 'Vinte seis' // -> false *preste atenção aqui*
4
5 var treze = 13
6 treze <= 13 // -> true
7
8 26 > 13 // -> true
9 'vinte seis' > 'Treze' // -> true
Comparadores de Igualdade
Além dos comparadores mostrados acima, também temos os comparadores de igualdade, que são constantemente usados em nossos códigos, porém tem algumas peculiaridades que se você não souber, certamente irá gerar erros nos seus programas. Mas fique tranquilo, é bem simples de entender a diferença entre eles, e irei lhe provar agora! Primeiro, vamos conhecer quais são estes outros operadores.
==: testa igualdade
!=: testa desigualdade
===: testa igualdade de forma restrita
!==: testa desigualdade de forma restrita
A grande diferença entre um operador e outro é que a primeira dupla (== e !=) ao comparar os valores, caso eles não sejam do mesmo tipo, procedem com uma particularidade do JavaScript chamada de Coerção de Tipo (ou conversão de tipo), e isso pode gerar muita dor de cabeça para você. Sério!
Irei explicar sobre coerção de tipo no próximo tópico, mas antes vamos tentar entender pelo código, de forma prática, como cada operador trabalha, e depois irei explicar de forma teórica e encerrar o assunto. Vamos lá!
1 '13' == 13 // -> true
2 '13' != 13 // -> false
3
4 '13' === 13 // -> false
5 '13' !== 13 // -> true
|
Vale ressaltar mais uma vez… Entender o que está acontecendo no código é super importante, e muitas vezes temos que realmente ler várias vezes e/ou ficar vários minutos para conseguir entendê-lo. E sim, isso é algo super importante, não tenha “dó” de investir tempo nisso! |
Neste próximo tópico irei lhe explicar o que aconteceu no código anterior, então, vamos para o próximo!
Coerção de Tipos
O nome assusta um pouco né?! E de fato devemos ter cuidado com isso pois surgem muitas <del>pérolas</del> bugs no seu código a partir deste esforço que o JavaScript faz para efetuar todas as instruções recebidas.
Sempre que você usa um operador no JavaScript (no caso então, faz uma operação), você irá receber um valor de retorno, nunca um erro, mesmo que você tente trabalhar com tipos diferentes de dados.
A coerção de tipos (ou conversão de tipos) é justamente isso! Quando tentamos fazer operações com tipos de dados diferentes, o JavaScript nos agracia com a conversão de um dos valores para algum outro tipo… Só que o grande e terrível problema disso é que dificilmente você consegue prever qual será este novo valor, pois as regras para tal conversão não são intuitivas, o que pode causar alguma(s) falha(s) em sua aplicação.
Como Evitar a Coerção de Tipos
Para evitar toda essa preocupação, você deve usar os operadores === e !==, que fazem a mesma verificação de igualdade que seus “primos”, porém NÃO fazem coerção de tipos!
ps: Por questões de segurança, sempre opte por usar os comparadores de igualdade restrita.
Parabéns! Agora você finalmente sabe o que é essa bendita coerção de tipos e como evitá-la! lol
|
Quando algo que não é obviamente um número é convertido para tal, o valor dessa operação é convertido para |
Operadores Lógicos
Sempre que pensamos na parte lógica do programa devemos pensar em valores booleanos, e para gerar estes valores booleanos a partir dos valores que nossas variáveis carregam, iremos usar os operadores lógicos, que são um tipo de operador binário, ou seja, necessitam de dois valores para geração de um terceiro.
ps: O operador ! é um operador lógico pois retorna um valor booleano, porém é uma exceção a regra por ser um operador unário.
Conheça agora os operadores lógicos:
-
&&: este operador é chamado de “E” lógico -
||: este operador é chamado de “OU” lógico -
!: este operador é chamado de “NÃO” lógico
&& E lógico
Este operador lógico e binário retorna true se ambos os valores (ou operandos) forem verdadeiros. Isso no caso será utilizado em estruturas condicionais, assunto que iremos abordar no próximo capítulo. Por enquanto você só precisa saber disso.
|| OU lógico
Este operador lógico e binário retorna true se um dos valores forem verdadeiros.
! NÃO lógico
Como já vimos anteriormente, este operador transforma o operando em booleano, porém com a peculiaridade de inverter seu valor truthy/falsy para um booleano de fato.
Curiosidades sobre os Operadores Lógicos
Quando utilizamos os operadores lógicos fora de estruturas condicionais, eles tem uma forma peculiar de trabalhar, que vale muito a pena ser entendida para que possamos deixar nosso código mais elegante e conciso.
Sempre que usamos && e ||, eles convertem o valor do lado esquerdo para um booleano, para saberem qual valor será retornado dessa operação.
Entendendo o Operador ||
O operador || retorna o valor da sua esquerda quando ele pode ser convertido para true, ou seja, quando seu valor é do tipo truthy, e sempre retorna o valor da direita caso contrário, independente de qual valor seja esse, até mesmo outro valor falsy. Veja isso na prática.
1 var esquerda = '' // -> valor do tipo falsy
2 var direita = 13 // -> valor do tipo truthy
3
4 esquerda || direita // -> 13
5
6 var direita = 0 // -> agora vamos atribuir este valor falsy na direita e ver o qu\
7 e acontece
8
9 esquerda || direita // -> 0
10
11 // Agora vamos deixar ambos os valores truthy
12
13 esquerda = 13
14 direita = 31
15
16 esquerda || direita // -> 13
Viram? Mesmo o valor da direita sendo falsy, ele é retornado pois a regra é: “se o valor da esquerda for falsy, retorne o da direita sem nem ver qual é”. E depois, quando alteramos o valor da esquerda para um valor truthy, ele foi retornado. Legal né?! =)
Vamos ver agora o outro operador.
Entendendo o Operador &&
Este operador faz o contrário. Quando o valor da esquerda é falsy, ele é retornado, independente de qual valor seja o da sua direita. E o valor da direita sempre será retornado quando o da esquerda for truthy, mesmo que este valor da direita seja falsy. Vamos ver o código para ficar mais claro.
1 var esquerda = NaN // -> valor do tipo falsy
2 var direita = 13 // -> valor do tipo truthy
3
4 esquerda && direita // -> NaN
5
6 var esquerda = 31 // agora vamos atribuir um valor truthy na esquerda e ver o que\
7 acontece
8
9 esquerda && direita // -> 13
10
11 // Agora vamos deixar o valor da direita falsy
12
13 direita = ''
14
15 esquerda && direita // -> ''
Muito bom! Estamos quase terminando, e a essa altura você já sabe de várias peculiaridades do JavaScript! Vamos em frente =)
Operador Ternário
Este operador é de fato muito poderoso, pois evita verbosidade no código, deixando-o então bem mais elegante.
Ele é chamado operador ternário pois envolve três peças em sua operação. Vamos analisá-lo abaixo. Primeiramente irei mostrá-lo em funcionamento e depois irei explicá-lo.
1 var usuario = ''
2
3 // usando o operador ternário
4 usuario ? usuario : 'convidado' // -> "convidado"
5
6 // atribuindo um valor a variável usuario
7 usuario = 'Eric'
8
9 // usando o operador ternário novamente
10 usuario ? usuario : 'convidado' // -> "Eric"
Como funciona isso? Lhe explico já!
Primeiramente criamos a variável usuario e atribuimos uma string vazia a ela. Ou seja, um valor falsy. Após isso, usamos o operador ternário que funciona da seguinte forma:
- Indicamos a variável ou condição que deve ser avaliada. No caso, usamos a variável
usuario. - Este valor a ser analisado será transformado em um booleano, a partir de seu valor truthy/false (está vendo a importância da teoria?!)
- Caso seu valor seja truthy, então o operador retorna a instrução após o sinal
?. Caso o valor seja falsy, o valor retornado será o que está após o sinal:. - Você pode retornar qualquer expressão JavaScript como valor de retorno dessa avaliação, veja outro exemplo:
var cozinheiro = false
- cozinheiro ? { receitas : [ ‘carnes’,’doces’,’tortas’ ] }
- console.log(‘mexido e olhe lá!’) // -> “mexido e olhe lá!”
Entendeu como funciona? Esse operador é muito legal! =D
ps: Altere o valor de cozinheiro para true e veja o que acontece!
Regras de Precedência
Para saber qual operação irá ocorrer primeiro, você precisa conhecer a ordem de precedência dos operadores. Confira abaixo a lista na ordem do maior (no topo) para o menor (embaixo) operador em relação a sua precedência.
-
++,--pré/pós incremento/decremento -
!altera valor booleano -
typeof, determina o tipo do operando -
*,/e%multiplica, divide e resto -
+e-soma e subtrai -
+concatena strings -
<,<=,>e>=comparação de ordem numérica -
<,<=,>e>=comparação de ordem alfabética -
==teste de igualdade -
!=teste de desigualdade -
===teste de igualdade restrita -
!==teste de desigualdade restrita -
&&E lógico -
||OU lógico -
?:operador ternário -
=atribuição à variável ou propriedade -
*=,/=,%=,+=e-=operação e atribuição
Veja mais sobre regras de precendência aqui
Conclusão
Finalmente terminamos! Bom, esse foi o maior capítulo até agora, e com certeza foi o mais interessante, por termos visto várias peculiaridades da linguagem JavaScript e termos sedimentado uma base sólida para os capítulos seguintes.