Isto é um bug no Javascript?

Carlos Brando
4 min readDec 4, 2015

--

Javascript é uma linguagem controversa. Existem aqueles que o defendem com unhas e dentes e esses programadores tem seus motivos. Mas quando observamos a quantidade de projetos que propõem substitui-lo como CoffeeScript, TypeScript, Dart e outros, percebemos que existe muita gente insatisfeita com a linguagem também. A realidade é que não importa em qual dos grupos você se encontra, simplesmente não podemos evita-la.

Eu sempre fico em cima do muro quando o assunto é Javascript. Tive muitos momentos agradáveis desenvolvendo projetos inteiramente nessa linguagem, mas também já me irritei com algumas características ruins da sua implementação em outras ocasiões.

O fato é que para se dar bem com Javascript é importante sair do básico e conhecer um pouco mais da linguagem, mas muitos programadores só estão interessados em aprender o suficiente para realizar pequenas tarefas e criar alguns scripts simples. Dessa forma, quando alguma coisa inesperada acontece, a culpa é sempre do pobre Javascript.

Durante esses anos como desenvolvedor eu separei alguns trechos de código em JavaScript que parecem ser bugs, mas na verdade não são. Abaixo veremos alguns desses trechos com uma rápida explicação sobre cada um deles e algumas dicas para evitar resultados inesperados.

Javascript não sabe somar

Números em Javascript são representados internamente com 64 bits e cada número pode ter no máximo 17 dígitos significativos. Isso tem algumas consequências interessantes como demonstrado no exemplo acima. É preciso ser bem cuidadoso com certos cálculos, principalmente quando a precisão é algo importante para o aplicativo.

Javascript não sabe somar — parte 2

No Javascript, o operador de soma (+) é usado tanto para somar valores numéricos como também para concatenar strings. Precisamos estar atentos a seguinte regra: durante uma operação de soma, quando um dos valores é do tipo string, tudo é convertido para este mesmo tipo e uma concatenação é realizada.

No primeiro exemplo, como iniciamos a soma com um string, todos os valores seguintes são imediatamente convertidos para este mesmo formato e depois são concatenados.

No segundo exemplo, temos inicialmente uma soma numérica (3 + 4 = 7) que é realizada normalmente, mas como o próximo valor é o string "5”, então o Javascript realiza a conversão do primeiro resultado e em seguida realiza uma concatenação dos valores, devolvendo no final o string “75”.

Javascript não sabe converter string para números

O método parseInt é muito utilizado e tem por objetivo converter strings em números inteiros. Basicamente o método aceita dois parâmetros: o primeiro é um string contendo o valor a ser convertido e o segundo é um inteiro que representa a base (decimal, binário, hexadecimal, etc.) na qual o string em questão está sendo representado.

O problema é que alguns livros e sites costumam explicar que o valor padrão da base (para quando ele não é informado) é 10, o que não é necessariamente uma verdade. Quando não informamos a base (radix), como no primeiro exemplo, o método parseInt utiliza a seguinte regra:

  • Se o string que estamos convertendo iniciar com “0x”, então o método assumirá a conversão com a base 16 (hexadecimal).
  • Se o string começar com “0” (como no exemplo acima) a base utilizada será 8 (octal).
  • Se o string iniciar com qualquer outro valor numérico, então a base padrão será 10 (decimal).
  • E se o primeiro caractere do string não puder ser convertido para um número, então parseInt retornará NaN. (“not a number”).

Desta forma, a dica é sempre informar a base na qual a conversão deve ser realizada, exatamente como foi feito no segundo exemplo.

Javascript não sabe fazer comparações

Podemos realizar comparações em Javascript com os símbolos <, >, <= e >=. Eles funcionam tanto para numerais como para strings. Mas quando o assunto é a comparações de igualdade, precisamos prestar atenção a alguns fatores.

O operador de igualdade duplo realiza uma coerção de tipos caso você esteja comparando dois valores de tipos diferentes, como podemos ver no exemplo acima. Embora aparentemente esse seja um resultado normal, em outros casos podemos ter resultados inesperados, como na seguinte comparação:

Porém, a linguagem também conta com um operador de igualdade triplo, que ignora a coerção de tipos:

Eu particularmente tenho como regra sempre utilizar o operador triplo ao realizar comparações de valores em JavaScript e isto tem me ajudado a evitar alguns erros de interpretação ao analisar o código e eventuais bugs decorrentes desta característica da linguagem.

Javascript não sabe contar

A propriedade length de objetos do tipo array em Javascript sempre retornará um número acima da maior posição do array e não a quantidade de itens no objeto, conforme vimos no exemplo acima.

Se você tentar recuperar o valor em uma posição não existente no array ele devolverá undefined.

Eu ❤ Javascript

Javascript possui muitas características boas, mas também possui algumas implementações realmente ruins. Por isso é importante gastar um pouco mais de tempo estudando mais a fundo o comportamento da linguagem. Depois de entender como algumas coisas realmente funcionam, descobrimos que nem tudo é bug.

Essas são apenas algumas curiosidades que consigo recordar sobre a linguagem. E você lembra de mais alguma?

--

--

Carlos Brando

Programmer, CTO at @enjoei, Author of two books about Ruby on Rails, and Host of the @grokpodcast.