Código JavaScript é uma sequência de instruções
Um programa em JavaScript nada mais é do que uma lista de instruções — comandos que o motor executa de cima para baixo. Declarar uma variável é uma instrução. Chamar uma função também. Um bloco if ou for é uma instrução. E cada uma delas é separada da próxima por ponto e vírgula.
Três instruções, três pontos e vírgula. A engine executa a primeira, depois a segunda, depois a terceira. Nada de mais.
Espaços em branco e indentação não fazem diferença nenhuma para o parser. Dá pra colocar as três numa linha só, separadas por ponto e vírgula, que o resultado é idêntico. A indentação existe para quem lê o código, não para a engine.
Blocos agrupam instruções
As chaves { } definem um bloco — um conjunto de instruções que a engine trata como uma unidade só. Você vai encontrar blocos por toda parte: corpos de funções, ramos de if, corpos de laços.
As duas chamadas de console.log dentro das chaves formam o corpo do if. Repare que não tem ponto e vírgula depois do } de fechamento — blocos não são instruções que precisam ser finalizadas. A instrução if como um todo termina quando o bloco termina.
Isso costuma pegar de jeito quem vem de linguagens onde todo } pede um ; depois. Em JavaScript, um bloco isolado ou um bloco de controle de fluxo não precisa disso.
Expressões x instruções
Vale deixar uma distinção clara desde cedo: expressões produzem um valor, instruções fazem alguma coisa.
2 + 3é uma expressão. Ela resulta em5.let x = 2 + 3;é uma instrução. Declara uma variável e atribui a ela o resultado de uma expressão.console.log("hi")é uma expressão (uma chamada de função retornaundefined), mas escrita sozinha numa linha com ponto e vírgula vira uma instrução de expressão.
Na maior parte do tempo, você nem precisa pensar nisso. O assunto só aparece quando você encontra arrow functions, ternários e situações em que o JavaScript espera uma expressão mas você entregou uma instrução (ou o contrário).
Precisa usar ponto e vírgula em JavaScript?
A resposta honesta é a seguinte: o JavaScript tem um recurso chamado Automatic Semicolon Insertion (ASI), ou inserção automática de ponto e vírgula, que coloca os pontos e vírgulas que você esqueceu na maioria das quebras de linha. Ou seja, um código assim roda sem problema:
Sem ponto e vírgula, sem erro. O ASI olha para cada quebra de linha e se pergunta: "o próximo token poderia dar continuidade à instrução atual?". Se não puder, ele insere um ponto e vírgula.
Por causa do ASI, dois estilos legítimos convivem por aí:
- Sempre com ponto e vírgula. É o que você vê na maioria dos projetos, tutoriais e guias de estilo.
- Sem ponto e vírgula. Adotado por alguns projetos modernos (Standard style, parte do ecossistema React). Depende do ASI mais alguns truques defensivos.
Os dois funcionam. Nenhum deles é "errado". O que é errado é misturar os dois estilos no mesmo arquivo — isso torna bugs muito mais difíceis de enxergar.
Onde o ASI te pega de jeito
O ASI acerta em mais ou menos 99% dos casos. O problema está no 1% restante: linhas que começam com um token capaz de dar continuidade à linha anterior. Os vilões são [, (, `, +, - e /.
Olha só este exemplo:
Você imaginaria que x e y seriam trocados. Só que o ASI não insere ponto e vírgula antes de [x, y], porque 10[x, y] é sintaticamente válido (indexar o número 10). O parser acaba lendo as linhas 2 e 3 como uma única expressão gigante, e você colhe um erro em tempo de execução ou uma saída esquisita.
A solução é colocar um ponto e vírgula no fim da linha 2:
Ou então, se você escreve no estilo sem ponto e vírgula, coloque um ponto e vírgula no início da linha que pode dar problema:
Aquele ; no início da linha é o truque defensivo usado por quem escreve sem ponto e vírgula. Parece esquisito até você entender o motivo.
A armadilha do return
Tem um caso específico do ASI que vale decorar, porque gera bugs silenciosos. Se você quebrar a linha logo depois do return, o ASI insere um ponto e vírgula bem ali, e a função acaba retornando undefined:
A ideia do autor era retornar um objeto. Só que o ASI viu o return no fim da linha e encerrou a instrução ali mesmo. Resultado: o objeto literal virou código inalcançável.
Para corrigir, basta começar o valor na mesma linha do return:
A mesma regra vale para throw, break, continue e yield — nunca coloque uma quebra de linha entre a palavra-chave e o valor que vem depois.
Uma regra simples que funciona
Se você está começando agora, o caminho mais tranquilo é este:
- Escreva o ponto e vírgula explicitamente no final de cada instrução.
- Não coloque depois do
}que fecha blocos deif,for,while, declarações de função ou corpos de classe. - Coloque depois do
}em literais de objeto ou em uma expressão de função atribuída a uma variável:const f = function() {};. - Use um formatador (Prettier, ESLint com alguma regra de estilo) e pare de se preocupar com isso. O formatador aplica o que o seu time combinou.
Essa regra não é lei universal — é só a convenção que você vai encontrar na maioria do código JavaScript por aí. Mantenha esse padrão até ter um bom motivo para fugir dele.
Sensibilidade a maiúsculas e identificadores
Duas regrinhas da sintaxe javascript que cabem aqui também:
- JavaScript diferencia maiúsculas de minúsculas (é case-sensitive).
userName,usernameeUserNamesão três identificadores diferentes. - Identificadores podem conter letras, dígitos,
_e$, mas não podem começar com um dígito. Também não podem ser palavras reservadas comoclass,returnoufunction.
O $ é válido, mas por convenção costuma ficar reservado para coisas de bibliotecas (o jQuery usou bastante no passado, e alguns sistemas de template ainda usam). Dificilmente você vai escolher esse caractere para suas próprias variáveis.
A seguir: Strict Mode
O JavaScript moderno roda discretamente em uma versão mais rígida da linguagem, chamada strict mode, que transforma uma série de comportamentos relaxados em erros de verdade. Módulos ES e corpos de class já são strict por padrão, mas vale entender o que isso muda na prática — é o tema da próxima página.
Perguntas frequentes
Precisa mesmo usar ponto e vírgula em JavaScript?
Tecnicamente não — o JavaScript tem o tal ASI (Automatic Semicolon Insertion), que insere o ; pra você na maioria das quebras de linha. Só que, na prática, quase todo time ainda escreve o ponto e vírgula de forma explícita, porque o ASI tem alguns casos traiçoeiros (linhas que começam com [, (, `, +, -, /) em que ele faz a coisa errada. O ideal é escolher um estilo e deixar um formatador como o Prettier cuidar disso pra você.
O que é Automatic Semicolon Insertion (ASI) no JavaScript?
O ASI é a regra que permite ao JavaScript inserir ponto e vírgula no fim da linha sempre que o próximo token não conseguiria dar continuidade à instrução atual. É por isso que let x = 1 funciona sem ;. O problema aparece quando a linha seguinte começa com algo que poderia continuar a anterior — tipo [ ou ( — e aí o JavaScript simplesmente gruda as duas linhas silenciosamente.
Como é a sintaxe básica de uma instrução em JavaScript?
Uma instrução é uma ordem pro motor executar — uma declaração de variável, uma chamada de função, um if, um loop. As instruções são separadas por ponto e vírgula (explícito ou inserido pelo ASI). Blocos de instruções ficam dentro de { }. Espaços em branco e indentação são ignorados pelo parser, ou seja, formatação é pra facilitar a vida do humano, não do motor.