JavaScript 2: decisões e validações

Hoje ensinas o programa a decidir: «se o cliente comprou mais de 1000 €, é VIP; senão, é normal». E usas isso para validar os dados de um cliente antes de os guardar.

🎯 No fim desta aula vais conseguir

🧰 Antes de começar

  1. Abre a pasta meu-crm no VS Code (File → Open Folder…).
  2. Abre o treino.html com o Live Server e abre a Consola (F12). Hoje voltamos a treinar no treino.js.
  3. Confirma que os resultados da aula 4 aparecem na Consola sem erros vermelhos.

😕 Faltaste à aula 4 ou o teu projeto não funciona? Descarrega o ponto de controlo da aula 4, descompacta-o e trabalha a partir dele.

Parte A — Decidir com if e else (≈ 20 min)

1 Se… senão…

Todos os dias tomas decisões: «se estiver a chover, levo guarda-chuva; senão, levo óculos de sol». Em JavaScript escreve-se assim:

A condição é uma pergunta cuja resposta só pode ser true (verdadeiro) ou false (falso), por exemplo totalCompras >= 1000 («o total de compras é maior ou igual a 1000?»). As chavetas { } marcam o bloco de instruções de cada caminho. O programa segue só um dos caminhos.

Cola este bloco no treino.js:

🤔 Prevê antes de executar: com totalCompras = 1250, que mensagem vai aparecer? E se mudares para 800? E para 1000 (atenção: é >=)? Escreve as três respostas no caderno e depois experimenta, gravando de cada vez.

✅ Deves ver na Consola: com 1250, Cliente VIP: portes grátis!; com 800, Cliente normal.; com 1000, outra vez Cliente VIP: portes grátis!. No fim, volta a pôr 1250.

😕 Aparece um erro vermelho
  • Unexpected end of input → falta fechar uma chaveta }. Cada { tem a sua }.
  • Assignment to constant variable → escreveste if (totalCompras = 1000) com um só =. Para comparar usa-se >=, ===… (vê a tabela do passo 3).
  • Identifier 'totalCompras' has already been declared → colaste o bloco duas vezes. Apaga a cópia.

Parte B — Validar os dados de um cliente (≈ 40 min)

2 Validar: nome, email e NIF

Imagina um CRM cheio de emails sem @ e de NIF com 8 algarismos: não dá para enviar faturas nem campanhas. Nas empresas diz-se «lixo entra, lixo sai». Por isso, antes de guardar um cliente, o programa tem de validar os dados, ou seja, verificar se fazem sentido.

Neste bloco aparecem várias coisas novas:

CódigoLê-se…
nome === ''«o nome é igual a texto vazio?» (duas plicas seguidas = texto sem nada lá dentro)
email.includes('@')«o email inclui um @?»
nif.length«quantos carateres tem o NIF?»
isNaN(nif)«o NIF não é um número?» (is Not a Number) → dá true se tiver letras
!isNaN(nif)o ! quer dizer NÃO: «o NIF é um número?»
… && …«… e …» (as duas coisas têm de ser verdade)

Cola o bloco no fim do treino.js:

✅ Deves ver na Consola: ✅ Nome OK: Rui Costa, ✅ O email tem @. e ✅ O NIF tem 9 algarismos.

Agora vais testar como um profissional. Muda um valor de cada vez, grava e confirma a mensagem. Depois volta a pôr o valor certo antes do teste seguinte:

Muda para…Mensagem que deves ver
const nome = '';❌ O nome é obrigatório.
const email = 'rui.costa.gmail.com';❌ O email não tem @.
const nif = '12345678'; (8 algarismos)❌ O NIF tem de ter 9 algarismos.
const nif = 'abcdefghi'; (letras)❌ O NIF tem de ter 9 algarismos.

⚠️ No fim dos testes, volta a pôr os valores originais ('Rui Costa', '[email protected]', '123456789'): o passo 3 e o desafio usam o email.

3 Juntar condições: E, OU e NÃO

Às vezes uma decisão depende de várias condições:

Neste bloco, const temEmail = email !== ''; guarda na variável a resposta à pergunta «o email é diferente de vazio?», ou seja, true ou false.

✅ Deves ver na Consola: ✅ Conseguimos contactar este cliente. e Este lead já comprou: passa-o a Cliente!

🤔 Prevê: se mudares, no passo 2, o email para '' (vazio), o que vai dizer a mensagem do contacto? E se depois mudares temTelefone para true? Experimenta e volta a pôr como estava.

😕 Erro Cannot access 'email' before initialization

Este bloco usa a variável email, que é criada no bloco do passo 2. Por isso tem de ficar por baixo dele. Corta o bloco do passo 3 e cola-o no fim do ficheiro.

Resumo: os operadores de comparação e lógicos

OperadorSignificaExemploResultado
===é igual a5 === 5true
!==é diferente de'Lead' !== 'Cliente'true
>é maior do que10 > 3true
<é menor do que10 < 3false
>=é maior ou igual a1000 >= 1000true
<=é menor ou igual a0 <= 0true
&&E (todas verdadeiras)5 > 3 && 2 > 4false
||OU (basta uma verdadeira)5 > 3 || 2 > 4true
!NÃO (troca o resultado)!truefalse

⚠️ = não é o mesmo que ===!

  • = guarda um valor numa variável (aula 4): let idade = 34; → «põe 34 na caixa».
  • === pergunta se dois valores são iguais: idade === 34 → «a caixa tem 34? sim ou não».

Truque para decorar: um = guarda, três === perguntam. (Existe também o ==, com dois, mas é “distraído”: acha que '5' == 5 é verdade. Nós usamos sempre o ===.)

🔎 Investiga

  1. No passo 2, muda o NIF para '12345678a' (9 carateres, mas com uma letra). Que mensagem aparece? Qual das duas partes da condição é que “apanhou” o erro?
  2. Para que serve o isNaN? Escreve na Consola isNaN('123'), isNaN('12a') e isNaN('Ana') e explica os resultados.
  3. Na validação do NIF, troca o && por || e testa outra vez com '12345678a'. O que acontece? Porque é que isso está errado? (Volta a pôr o &&.)
  4. No passo 1, escreve if (totalCompras = 1000), só com um =. Lê o erro que aparece. O que é que o JavaScript pensou que querias fazer? (Volta a pôr como estava.)

✍️ Exercícios (fazem parte do teu projeto)

Estes exercícios não têm o código pronto: usa o que aprendeste hoje. Escreve-os no fim do treino.js, por baixo do código da aula 5 (e por cima do comentário AULA 7: COLAR AQUI). Lembra-te: não podes repetir nomes de variáveis que já existem no ficheiro.

E1 · Validar o telefone

Cria uma variável telefone com um número de telefone e mostra «✅ Telefone válido.» ou «❌ Telefone inválido.». Um telefone português é válido se tiver exatamente 9 algarismos e começar por 9 (telemóvel) ou por 2 (rede fixa).

💡 Dica: guarda o telefone como texto (entre aspas), tal como o NIF. telefone[0] dá o primeiro carater (as posições começam no 0) e compara-se com '9', também entre aspas. Para os 9 algarismos, inspira-te na validação do NIF. Vais precisar de && e de ||: põe a parte do OU entre parênteses. Testa com '912345678' e '226789123' (válidos) e com '812345678' e '91234567' (inválidos).

E2 · Portes de envio

Cria uma variável valorEncomenda e mostra os portes de envio desta loja online:

  • encomenda de 50 € ou mais → «Portes: grátis»;
  • encomenda de menos de 50 € → «Portes: 3,99 €»;
  • encomenda de 0 € ou menos → «❌ Encomenda inválida.»

💡 Dica: quando há mais de dois caminhos, usa-se else if: if (…) { … } else if (…) { … } else { … }. O programa testa as condições por ordem e segue a primeira que for verdadeira: pensa bem em qual deves testar primeiro. Testa com 42, 50, 0 e -5.

⭐ Desafio · Um email a sério

A nossa validação só verifica se há um @, por isso aceita rui@gmail. Melhora-a: usando a variável email que já existe, mostra «✅ Email com formato válido.» só se o email tiver um @ (que não seja o primeiro carater) e um ponto depois do @, com pelo menos um carater entre os dois.

💡 Dica: email.indexOf('@') dá a posição do @ (ou -1 se não houver nenhum) e email.lastIndexOf('.') dá a posição do último ponto. Compara as posições. Para testar, muda o valor do email no bloco do passo 2: '[email protected]' é válido; 'rui.costa@gmail', '@gmail.com' e '[email protected]' não são.

📦 O que mostrar ao professor

⏱️ Se sobrar tempo

🤖 Pedir ajuda à IA (opcional)

Um bom programador testa com muitos casos diferentes. Podes pedir a uma IA que te ajude a pensar em casos de teste (sem código). Copia este pedido e cola-o na IA:

📖 Palavras novas

Condição
Pergunta cuja resposta é true ou false, ex.: totalCompras >= 1000.
if / else if / else
Se / senão se / senão: escolhem que bloco de código corre.
Operador de comparação
Compara dois valores: ===, !==, >, <, >=, <=.
Operador lógico
Junta ou inverte condições: && (E), || (OU), ! (NÃO).
Validação
Verificar se os dados fazem sentido antes de os guardar.
.includes(…)
Diz se um texto contém outro: '[email protected]'.includes('@') → true.
isNaN(…)
Diz se um valor não é um número.
texto[0]
O primeiro carater de um texto (as posições começam no 0).
.indexOf(…)
Diz a posição de um carater num texto (ou -1 se não existir).