O Ponto e vírgula e o Javascript;

Quando procuramos informações, posts, comentários, etc. sobre ponto e vírgula no javascript, não é incomum nos depararmos com discussões onde pessoas apontam que o ponto e vírgula é completamente inútil. Por outro lado, há pessoas que advogam que o ponto e vírgula é realmente obrigatório, independente das regras de ASI. Realmente é muito difícil nos depararmos com algum tipo de problema relacionado ao assunto, mas eu acredito que é sempre bom procurarmos entender o funcionamento das linguagens do dia a dia, principalmente o javascript, que está cada vez mais presente em todas as tecnologias que utilizamos.

logo-javascript

Podemos notar que, em casos como um simples:

console.log('console.log com ponto e vírgula');

Funcionam exatamente como:

console.log('console.log sem ponto e vírgula')

Isso acontece justamente por conta das regras de inserção automática de ponto e vírgula. Em casos como este, independente da sua linha de pensamento, das suas convicções, etc, o código vai funcionar exatamente como esperado. Então vamos analisar uma das regras para que isso aconteça:

When, as the program is parsed from left to right, a token (called the offending token) is encountered that is not allowed by any production of the grammar, then a semicolon is automatically inserted before the offending token if one or more of the following conditions is true:

  • The offending token is separated from the previous token by at least one LineTerminator.
  • The offending token is }.

Ou seja, ao interpretar o seu programa da esquerda para a direita, se um símbolo é encontrado e ele não faz sentido naquele contexto, caso o símbolo ofensor estiver separado por pelo menos uma quebra de linha, ou o símbolo ofensor é um }, um ponto e vírgula será incluído automaticamente:

var numero = 123
var texto = "123"

Neste caso, o código é analisado da direita para a esquerda, quando o v do var que se encontra na segunda linha é encontrado, ele não faz sentido naquele contexto, e como vem depois de uma quebra de linha, um ponto e virgula é incluído automaticamente no fim de var numero = 123.

Agora imagine a seguinte situação:

var a = 1
var b = 2
var c = a + b

(function () {
  console.log('log de um iife')
})()

O que está acontecendo? Quando este código for analisado, a primeira linha é perfeitamente válida, assim como a segunda. Porém, ao se deparar com ( do iife, o código será interpretado como se o você estivesse utilizando a variável b como uma function, passando uma outra function como argumento. Neste caso, o seu código não funcionará, e você poderá ver um erro como Uncaught TypeError: b is not a function

Provavelmente este não é um caso comum de acontecer, porém caso você não conheça as regras, poderá encontrar algum problema. E isso é válido até para casos onde você utiliza o ponto e vírgula. Imagine a seguinte situação: Você escreve uma function que irá retornar a soma de a e b como no exemplo anterior, mas por algum motivo, há uma quebra de linha logo após o return:

function somarAeB() {
  var a = 1;
  var b = 1;

  return
    a + b;
}

ou

function somarAeB() {
  var a = 1;
  var b = 1;

  return
  {
    a + b;
  }
}

Esse código possui algum erro? Se a sua intenção era retornar a soma de a + b, então neste caso você possui um bug. Há uma regra que fala:

When, as the program is parsed from left to right, a token is encountered that is allowed by some production of the grammar, but the production is a restricted production and the token would be the first token for a terminal or nonterminal immediately following the annotation “[no LineTerminator here]” within the restricted production (and therefore such a token is called a restricted token), and the restricted token is separated from the previous token by at least one LineTerminator, then a semicolon is automatically inserted before the restricted token.

Ou seja, se uma quebra de linha for encontrada após um “restricted production” (entenda return, continue, break, throw), um ponto e vírgula será incluído. Então na prática, o código que você realmente escreveu é:

function somarAeB() {
  var a = 1;
  var b = 1;

  return;
    a + b;
}

Caso você queira se entender melhor o funcionamento do ASI, você pode ler a documentação sobre o assunto.

Por hoje é só 😉

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s