Desenvolvimento

25 ago, 2016

JavaScript: o lado obscuro

Publicidade

JavaScript é uma linguagem que todos programadores modernos precisam saber. É um pouco diferente de outras linguagens, o que acaba confundindo em alguns momentos. Tem como característica conceitos de função de primeira classe, tipos dinâmicos, herança de protótipo, callbacks e closure. Chegou a um nível que antes era limitado somente aos navegadores, para plataformas completas server-side fáceis de construir, rápidas e escaláveis. Atualmente, é fácil encontramos varias ferramentas de build systems, mini frameworks para criação de aplicação e ferramentas de desenvolvimento que sincronizam código que você está trabalhando com o navegador. Tudo isso rodando server-side com JavaScript. Esse universo cresce a cada dia. Vemos na parte de client-side novos frameworks eficientes focando em desempenho, flexibilidade, modernas arquiteturas e teste unitários. Técnicas como VirtualDOM, que estão sendo muito faladas atualmente, e web components, que todo dia sai um framework novo usando esse conceito de componentização, encapsulamento e reutilização.

Tudo isso é muito bom. É legal ver toda essa evolução no JavaScript, mas temos alguns comportamentos esquisitos e problemas na linguagem, e é sobre isso que se trata este artigo. Um lado obscuro que é pouco falado, às vezes até inexplicável em algumas situações. Então, hoje, vamos mergulhar bem a fundo nessas características e entender um pouco o que acontece. Se você é um desenvolvedor web, simplesmente não pode deixar de conhecer essas “coisas estranhas” com as quais você pode se deparar em algum com um caso e, quando ocorrer, você vai saber o que está acontecendo com sua aplicação.

js-1

O que são esses comportamentos estranhos

Não existe um motivo apenas para explicar esses comportamentos estranhos. Muitos desses comportamentos têm uma explicação devido à forma como o JavaScript trata os literais. O JavaScript permite converter tipos literais usando no início de um tipo “!” para boolean e “+” ou “-” para inteiro. Cada literal (array, string, object etc.) se comporta de uma forma. Entendendo esse comportamento, conseguimos explicar algumas dessas coisas estranhas. Outro motivo é a conversão de tipos de dados. O JavaScript é uma linguagem dinamicamente tipada. Isso significa que você não precisa especificar o tipo de dado de uma variável quando declará-la. São convertidas no momento de execução do script. Já outros comportamentos eu diria que não têm explicação. Defino como bugs que há muito tempo permanecem na linguagem. Operações que retornam resultados que não fazem sentido algum.

Teoricamente, é mais ou menos isso. Esse são alguns motivos, mas na realidade têm muito outros detalhes para explicar todo esse comportamento esquisito.  Vou apresentar alguns exemplos e comentar um pouco sobre o que acontece em cada caso. Vamos ver na prática o quanto isso é estranho, e eu diria que alguns casos são até bizarros pelo resultado.

Comparações esquisitas

Vamos começar com comparações entre tipos e valores. Todo mundo sabe que JavaScript permite comparar tipos diferentes. O operador == ( igual a ) permite comprar apenas o valor e  === ( igual tipo e valor ) compara primeiro o tipo e depois o valor, sendo assim:

> “50” == 50
// true
> “50” === 50
// false

Ok, até aí tudo bem. JavaScript é cross-type, então consigo comprar valores com tipos diferentes sem muito trabalho. Agora de fato vamos começar com as coisas estranhas:

Comparando array igual a array retorna falso.

> [] == []
// false

Comparando array igual a não array retorna verdadeiro.

> [] == ![]
// true

Comparando objeto array igual a String com 3 vírgulas retorna verdadeiro.

> Array(4) == “,,,”
// true

Comparando inteiro com boolean retorna verdadeiro.

> 0 == false
// true

Agora complicou. Olhando o resultado de todas as comparações não faz sentido algum. Comparando um array com array, são tipos iguais com valores iguais e o retorna falso. Um array com um não array, tipos iguais mas explicitamente falando que um é não array e o retorno é verdadeiro. Zero é igual a falso. Enfim, bem esquisito.

js-2

Tipos de dados

Analisando um pouco do tipo de dado, um dos esquisitos é o null. O null é ausente de valor significativo e também é um objeto em JavaScript. Porém, null não é considerado uma instância de um objeto, isso é muito fácil de confundir se apenas verificar o tipo. Veremos agora um exemplo:

> typeof null
// object

Porém, null não é uma instância de objeto, o retorno é false.

> null instanceof Object
// false

Isso acontece também com string.

> “Uma string qualquer” instanceof String
// false

Outro tipo é o NaN que significa not a number. Se verificarmos qual o tipo de um NaN, ele retorna que é um number. Um not a number é um number, bem estranho de entender. E se compararmos um NaN igual a NaN, retorna false. Nem eles se entendem.

> typeof NaN
// number
> NaN == NaN
// false

js-3

Cálculos mágicos

Agora vamos ver que JavaScript não sabe calcular. Nessa etapa, veremos um comportamento muito estranho, que, na minha opinião, é um bug. Isso pode causar grandes problemas, principalmente quando a precisão dos cálculos é importante na sua aplicação.

Digitando 16 dígitos de 9, magicamente aumenta o valor.

> 9999999999999999
// 10000000000000000

Mesmo subtraindo com -1, retorna o mesmo valor.

> 9999999999999999 – 1
// 10000000000000000

Soma de  0.1 + 0.2 é diferente de 0.3. Quando vemos o resultado apenas de 0.1 + 0.2, o retorno é 0.30000000000000004. Realmente não sabe somar.

> 0.1 + 0.2 == 0.3
// false
> 0.1 + 0.2
// 0.30000000000000004

Somar uma string com valor 2 mais 1 inteiro, o retorno é uma string com valor 21. O JavaScript entende que o operador “+” está concatenando com o 1 inteiro. Usando o operador “-” consigo subtrair com o valor da string.

> “2” + 1
// 21
> “2” - 1
// 1

Mas como faço para somar um valor de uma string, já que o JavaScript permite subtrair? Muito simples e complexo ao mesmo tempo:

> “2” - - 1 
// 3

Por favor, não façam isso em casa nem no trabalho.

im

JavaScript tem suas peculiaridades e é uma linguagem que tem características boas, sim. Não é à toa que sua popularidade está em alta ultimamente. Este artigo é para entender um pouco mais a fundo o seu funcionamento e suas particularidades. É pelo conhecimento de como se comporta e saber quais os resultados disso.

Então, essa é a informação que quero passar para todos os desenvolvedores front-end que gostam de JavaScript. E obrigado por ler até aqui!