Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA
LiçãoIniciantecódigo testado

Variáveis em JavaScript: como declarar e usar

Declarar, atribuir e ler valores em JavaScript, com tipagem dinâmica, regras de nome e o ReferenceError que aparece quando o nome não confere.

Rodolfo Mori6 min de leitura

Variável é um nome que aponta para um valor guardado na memória. Você cria o nome com let ou const, coloca um valor nele e passa a usar o nome no lugar do valor pelo resto do programa.

A forma curta, para já sair escrevendo: const quando o valor não vai mudar, let quando vai. É a decisão inteira nos primeiros meses. Se você quer o detalhe de escopo, hoisting e a diferença para o var antigo, isso tem lição própria em var, let e const na prática. Aqui o assunto é outro: como o nome se comporta, o que ele aceita como valor e o erro que aparece quando ele não existe.

Uma variável é uma gaveta com nome

Imagine uma bancada com gavetas. Se você guarda o total do pedido numa gaveta sem etiqueta, depois precisa abrir todas para encontrar. Uma variável liga um nome a um valor para o programa localizar e reaproveitar a informação. Em const total = 50, total é a etiqueta e 50 é o valor guardado.

A imagem da gaveta ajuda no primeiro contato, mas o comportamento técnico é uma ligação na memória, não uma caixinha física. Valores primitivos e objetos são copiados de maneiras diferentes, assunto de outra lição. Aqui, faça uma missão pequena: crie preco, quantidade e subtotal; calcule a terceira usando as duas primeiras e imprima. Depois troque apenas quantidade. Se o resultado muda sem você reescrever o preço na conta, o motivo de dar nomes já ficou visível.

Declarar, atribuir e ler

js
let cliente = 'Ana Souza';
const CEP_DA_LOJA = '01310-100';
let itensNoCarrinho = 0;

itensNoCarrinho = 3;

console.log(cliente, CEP_DA_LOJA, itensNoCarrinho);
Ana Souza 01310-100 3

Três operações diferentes acontecem nesse trecho, e vale separá-las com nome próprio porque as mensagens de erro do JavaScript falam nesses termos:

  • Declarar é criar o nome: let itensNoCarrinho.
  • Inicializar é dar o primeiro valor na mesma linha: = 0.
  • Atribuir é trocar o valor depois: itensNoCarrinho = 3.

Um let declarado sem valor não é erro — ele nasce valendo undefined, e passa a valer alguma coisa quando você atribuir. Um const sem valor, sim: não existe constante para preencher depois.

O mesmo nome, outro tipo: tipagem dinâmica

Em JavaScript o tipo pertence ao valor, não ao nome. A mesma variável pode guardar texto, número e objeto ao longo do programa:

js
let campo = '3';
console.log(typeof campo, campo);

campo = 3;
console.log(typeof campo, campo);

campo = { quantidade: 3 };
console.log(typeof campo, campo);
string 3 number 3 object { quantidade: 3 }

Isso é tipagem dinâmica. Em Java ou C você declararia int quantidade e o compilador reclamaria na hora de guardar um texto ali. Aqui ninguém reclama — e a conta sai errada bem mais tarde:

js
let quantidade = '2';
const preco = 149.9;

console.log(preco * quantidade);
console.log(preco + quantidade);
299.8 149.92

A multiplicação funcionou, porque * só existe para números e a linguagem converteu o '2'. A soma não: o + também serve para juntar texto, e diante de uma string ele escolheu concatenar. 149.9 colado em '2' deu '149.92' — um preço plausível, silenciosamente errado. Esse é o motivo de existir uma lição inteira sobre converter string em número.

O que pode virar nome de variável

A regra formal: o nome começa com letra, _ ou $, e depois aceita letras, números, _ e $. Letra aqui é Unicode, então acento passa:

js
const _codigoInterno = 'PED-4821';
const $seletorDoBotao = '#finalizar';
const precoUnitário = 289.9;
const cliente2 = 'Bruno';

console.log(_codigoInterno, $seletorDoBotao, precoUnitário, cliente2);
PED-4821 #finalizar 289.9 Bruno

Passa, mas repare que “o motor aceita” e “é boa ideia” são coisas diferentes. O _ no começo é convenção antiga para “isto é interno, não mexa”; o $ ficou marcado pelo jQuery e hoje é comum em variável que guarda um elemento da página. Acento, na prática, ninguém usa.

O que não passa é começar com número:

js
const 2produtos = 4;
file:///private/tmp/loja/l4-nome-numero.mjs:1 const 2produtos = 4; ^

SyntaxError: Invalid or unexpected token Node.js v24.16.0

Nem usar hífen, que a linguagem lê como operador de subtração:

js
const preco-final = 199;
file:///private/tmp/loja/l4-nome-hifen.mjs:1 const preco-final = 199; ^^^^^

SyntaxError: Missing initializer in const declaration Node.js v24.16.0

A mensagem parece não ter nada a ver, e tem: o motor leu const preco — uma constante sem valor — e depois um -final = 199 solto. Ele reclama do que entendeu, não do que você quis dizer. Vale a pena se acostumar com isso desde cedo, porque SyntaxError quase sempre aponta uma linha depois do problema real.

Maiúscula conta, e palavra reservada não vale

JavaScript diferencia maiúscula de minúscula. totalPedido e totalpedido são dois nomes distintos, e o segundo nunca foi criado:

js
const totalPedido = 589.7;

console.log(totalpedido);
file:///private/tmp/loja/l4-case.mjs:3 console.log(totalpedido); ^

ReferenceError: totalpedido is not defined at file:///private/tmp/loja/l4-case.mjs:3:13 Node.js v24.16.0

Guarde essa mensagem: is not defined significa este nome não existe em nenhum escopo visível daqui. Nas primeiras semanas ela é quase sempre erro de digitação; depois, import esquecido.

A outra restrição são as palavras que a linguagem já usa — class, const, return, function, new, if, for e companhia:

js
const class = 'premium';
file:///private/tmp/loja/l4-reservada.mjs:1 const class = 'premium'; ^^^^^

SyntaxError: Unexpected token ‘class’ Node.js v24.16.0

Na prática ninguém tenta declarar const if. O caso real é class, quando você está mexendo em HTML e quer guardar o nome de uma classe CSS — use classeCss ou className, que é como o próprio DOM chama.

Atribuir sem declarar cria uma global implícita

Esta é a armadilha mais silenciosa da linguagem. Se você atribuir a um nome que nunca foi declarado, o JavaScript antigo não reclama: ele cria a variável no escopo global e segue.

js
function calcularFrete(peso) {
  taxa = 12.5;
  return taxa + peso * 1.5;
}

console.log(calcularFrete(2));
console.log(typeof taxa, taxa);
15.5 number 12.5

O taxa estava dentro da função, e depois da chamada ele existe fora dela. Duas funções diferentes que usem o mesmo nome passam a escrever uma por cima da outra, e o bug aparece longe da causa.

Modo estrito acaba com isso — e todo módulo ES já roda em modo estrito por padrão. O mesmo código num arquivo .mjs, ou num <script type="module">:

js
function calcularFrete(peso) {
  taxa = 12.5;
  return taxa + peso * 1.5;
}

console.log(calcularFrete(2));
file:///private/tmp/loja/l4-global-modulo.mjs:2 taxa = 12.5; ^

ReferenceError: taxa is not defined at calcularFrete (file:///private/tmp/loja/l4-global-modulo.mjs:2:8) at file:///private/tmp/loja/l4-global-modulo.mjs:6:13 Node.js v24.16.0

Mesmo arquivo, mesma linha, comportamento oposto. É por isso que a recomendação prática é: escreva em módulo. Você troca um bug invisível por uma mensagem clara na linha exata.

Erros comuns

Quatro mensagens cobrem quase tudo que dá errado com variável nesta fase:

mensagem o que aconteceu onde olhar
x is not defined o nome não existe em nenhum escopo dali digitação, maiúscula, import faltando
Cannot access 'x' before initialization o nome existe, você chegou antes da declaração ordem das linhas
Assignment to constant variable. reatribuição de um const trocar por let ou parar de reatribuir
Identifier 'x' has already been declared dois let/const com o mesmo nome no mesmo escopo copiar e colar

As duas últimas, e o mecanismo de escopo por trás delas, estão detalhadas em var, let e const na prática. A primeira você acabou de ver acontecer duas vezes nesta lição.

Como nomear na prática

O motor aceita quase qualquer nome; quem lê o código, não. Quatro hábitos que resolvem 90% dos casos:

  • camelCase para tudo que é valor comum: precoUnitario, totalDoPedido.
  • Booleano começa com verbo de estado: temFreteGratis, estaPago. Se o nome não puder ser respondido com sim ou não, ele não deveria guardar booleano.
  • Nome diz o que é, não o tipo: precos, não arrayDePrecos.
  • MAIUSCULA_COM_UNDERSCORE só para configuração fixa do módulo, definida uma vez e nunca tocada — CEP_DA_LOJA, LIMITE_DE_PARCELAS.
js
const precoUnitario = 289.9;
const quantidade = 2;
const subtotal = precoUnitario * quantidade;
const temFreteGratis = subtotal >= 199;

console.log(`subtotal R$ ${subtotal.toFixed(2)} · frete grátis: ${temFreteGratis}`);
subtotal R$ 579.80 · frete grátis: true

Nome bom economiza comentário. Se você precisou escrever // quantidade de itens ao lado de const q = 2, o comentário era o nome.

A próxima lição olha para o outro lado da variável — o valor que está dentro dela — em tipos de dados e o operador typeof. O guia de JavaScript mostra a trilha inteira em ordem.

Prefere aprender em vídeo?

Tem uma aula sobre este assunto no nosso canal.

Ver todos os vídeos do canal
  • javascript
  • variaveis
  • tipagem dinamica
  • nomes
  • referenceerror

Perguntas frequentes

Posso usar acento e cedilha no nome de uma variável?
O motor aceita, porque identificadores seguem Unicode. Na prática ninguém usa: quebra em busca, atrapalha quem lê teclado diferente e destoa de todo código de biblioteca. Deixe o acento para strings e comentários.
Preciso dizer o tipo da variável como em Java?
Não. O tipo pertence ao valor, não ao nome, e muda quando você reatribui. Essa liberdade é confortável no começo e vira problema em projeto grande — é o buraco que o TypeScript veio tapar.
Qual a diferença entre declarar e atribuir?
Declarar é criar o nome, com let ou const. Atribuir é colocar um valor nele. Declarar sem atribuir deixa a variável valendo undefined; atribuir sem declarar é o que gera a global implícita ou um ReferenceError.
Por que o meu código diz que a variável não está definida se eu criei ela?
Quase sempre é diferença de maiúscula ou minúscula no nome, ou o nome está em outro bloco. JavaScript distingue totalPedido de totalpedido, e trata os dois como variáveis diferentes que não se conhecem.

Dúvidas e comentários

Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.

Todo o código deste artigo foi executado em Node 24.16.0, e as saídas exibidas são as reais — como produzimos este conteúdo.

Fontes consultadas

  1. MDN — Gramática e tipos: declarações — developer.mozilla.org
  2. ECMAScript — Identifier Names — tc39.es

Continue por aqui