JavaScript Moderno (ES6+)
1. Rodando JavaScript no Navegador
Antes de qualquer código, você precisa saber onde executar JavaScript. O navegador já vem com um ambiente completo para rodar JS — sem instalar nada.
Console do DevTools
Todo navegador moderno tem as Ferramentas de Desenvolvedor (DevTools). O Console dentro delas é um ambiente onde você pode digitar e executar JavaScript diretamente.
Como abrir:
- Windows/Linux: pressione
F12ouCtrl + Shift + J - Mac: pressione
Cmd + Option + J - Ou clique com o botão direito em qualquer página → Inspecionar → aba Console
Você verá uma área com > onde pode digitar código e pressionar Enter para executar. Experimente:
console.log("Olá, mundo!");
O Console é ótimo para testar trechos curtos e ver erros. Ele vai ser seu melhor aliado durante a atividade.
Executando um arquivo .js no navegador
Para rodar um arquivo inteiro (como o da atividade), você tem duas opções:
Opção A — via HTML: crie um index.html mínimo que carrega o seu arquivo:
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"></head>
<body>
<script src="catalogo.js"></script>
</body>
</html>
Abra o index.html no navegador, pressione F12 e veja a saída no Console.
Opção B — cole no Console: abra qualquer página, cole o conteúdo do arquivo no Console e pressione Enter. Funciona para arquivos curtos.
Dica: quando um
console.logimprime um objeto, clique na seta▶ao lado para expandir e ver todas as propriedades.
2. Declaração de Variáveis: var, let e const
Variáveis são espaços na memória onde guardamos dados para usar mais tarde. Em JavaScript existem três formas de declarar uma variável: var, let e const. As três existem no JS atual, mas não nasceram ao mesmo tempo e têm comportamentos importantes diferentes.
var — a forma original (ES1, 1997)
var foi a única forma de declarar variáveis no JavaScript por quase 20 anos. Ela funciona, mas tem comportamentos que causam bugs difíceis de detectar:
- Escopo de função: uma variável
vardeclarada dentro de umifouforexiste fora dele - Hoisting:
varé “elevada” para o topo do escopo antes do código rodar, o que pode causar resultados inesperados
// Problema de escopo com var
if (true) {
var mensagem = "estou dentro do if";
}
console.log(mensagem); // "estou dentro do if" — vazou para fora!
// Com let, isso seria um erro:
if (true) {
let mensagemLocal = "estou dentro do if";
}
console.log(mensagemLocal); // ReferenceError: mensagemLocal is not defined
Hoje em dia, var é considerada obsoleta em código moderno. Você vai encontrá-la em código legado e tutoriais antigos, mas evite usar em código novo.
let — variável de escopo de bloco (ES6, 2015)
let foi introduzida no ES6 exatamente para corrigir os problemas do var. Use quando o valor precisa ser atualizado ao longo do tempo.
- Escopo de bloco: existe apenas dentro do bloco
{}onde foi declarada - Pode ser reatribuída: o valor pode mudar
let pontuacao = 0;
pontuacao = pontuacao + 10; // funciona — reatribuição permitida
pontuacao += 5; // forma abreviada, mesmo efeito
console.log(pontuacao); // 15
Um uso muito comum é como acumulador dentro de loops:
const musicas = ["Bohemian Rhapsody", "Hotel California", "Stairway to Heaven"];
let totalCaracteres = 0;
for (const musica of musicas) {
totalCaracteres = totalCaracteres + musica.length;
}
console.log(`Total de caracteres: ${totalCaracteres}`); // 54
const — constante de bloco (ES6, 2015)
const também foi introduzida no ES6. Use quando o valor não deve mudar depois de declarado.
- Escopo de bloco: igual ao
let - Não pode ser reatribuída: tentativa gera
TypeError
const anoLancamento = 2015;
anoLancamento = 2020; // TypeError: Assignment to constant variable.
Atenção:
constimpede a reatribuição da variável, mas não impede a mutação de objetos e arrays. Isso é um detalhe avançado — não se preocupe por agora, apenas lembre: useconstcomo padrão e troque paraletquando precisar reatribuir.
Regra prática: comece sempre com const. Se o código reclamar (ou você precisar reatribuir), troque para let. Nunca use var.
3. Objetos
Um objeto em JavaScript é uma estrutura que agrupa dados relacionados em pares chave-valor. É a forma natural de representar uma “coisa” com várias propriedades — um produto, um usuário, uma música.
Pense nisso como uma ficha: cada linha da ficha tem um rótulo (chave) e um valor.
const musica = {
titulo: "Bohemian Rhapsody",
artista: "Queen",
ano: 1975,
duracao: 354, // em segundos
};
Acessando propriedades
A forma mais comum é a notação de ponto:
console.log(musica.titulo); // "Bohemian Rhapsody"
console.log(musica.ano); // 1975
Também existe a notação de colchetes, útil quando o nome da propriedade está em uma variável:
const campo = "artista";
console.log(musica[campo]); // "Queen"
Objetos dentro de arrays
É muito comum ter um array onde cada item é um objeto:
const playlist = [
{ titulo: "Bohemian Rhapsody", artista: "Queen", ano: 1975 },
{ titulo: "Hotel California", artista: "Eagles", ano: 1977 },
{ titulo: "Imagine", artista: "Lennon", ano: 1971 },
];
console.log(playlist[0].artista); // "Queen"
console.log(playlist[2].titulo); // "Imagine"
4. Arrays e Formas de Percorrê-los
Um array é uma lista ordenada de valores. Cada item tem uma posição (índice), começando em zero. Arrays existem no JavaScript desde o início (ES1, 1997), mas as formas de trabalhar com eles evoluíram muito ao longo dos anos.
const generos = ["Rock", "Pop", "Jazz", "Metal"];
console.log(generos[0]); // "Rock"
console.log(generos.length); // 4
Formas de percorrer um array
Existem várias formas de iterar sobre um array. Cada uma surgiu em um momento diferente e tem um propósito diferente:
for clássico — ES1 (1997)
A forma mais antiga e genérica. Você controla manualmente o índice.
for (let i = 0; i < generos.length; i++) {
console.log(generos[i]);
}
Ainda é útil quando você precisa do índice para algo específico (ex: numerar itens), mas para simplesmente percorrer é verboso demais.
for...in — ES1 (1997)
Criado para percorrer as chaves de um objeto. Funciona em arrays (os índices são as chaves), mas é considerado inadequado para arrays porque pode incluir propriedades extras que não são itens da lista.
const obj = { nome: "Queen", pais: "UK" };
for (const chave in obj) {
console.log(chave, "→", obj[chave]);
}
// nome → Queen
// pais → UK
Evite usar
for...inem arrays. Use nos objetos, onde faz sentido.
forEach — ES5 (2009)
O primeiro método funcional de array. Recebe uma função de callback que é executada uma vez para cada item. Não retorna nada — é só para percorrer e executar código.
generos.forEach(function(genero) {
console.log(genero);
});
// Com arrow function (veremos a seguir):
generos.forEach((genero) => {
console.log(genero);
});
Mais expressivo que o for clássico, mas não permite break para parar no meio.
for...of — ES6 (2015)
A forma mais moderna e recomendada para percorrer arrays (e qualquer coisa “iterável”, como strings). Sintaxe limpa, permite break, não precisa de índice.
for (const genero of generos) {
console.log(genero);
}
Na atividade você vai usar principalmente
for...of. É a forma mais legível e moderna para percorrer arrays.
Métodos úteis de array
Além de percorrer, arrays têm métodos embutidos para consultar e manipular dados. Os listados abaixo existem desde o ES3/ES5 (1999–2009) e são os mais usados no dia a dia:
| Método | O que faz | Retorna |
|---|---|---|
push(item) | Adiciona item ao final | novo comprimento |
pop() | Remove e retorna o último item | item removido |
shift() | Remove e retorna o primeiro item | item removido |
unshift(item) | Adiciona item ao início | novo comprimento |
splice(i, n) | Remove n itens a partir do índice i | array removido |
slice(i, j) | Retorna cópia de um trecho (não altera original) | novo array |
indexOf(item) | Retorna o índice do item (ou -1 se não encontrar) | número |
includes(item) | Verifica se o item existe | boolean |
join(sep) | Une todos os itens em uma string | string |
reverse() | Inverte a ordem dos itens (altera o original) | array |
Exemplos com o contexto de playlist:
const generos = ["Rock", "Pop", "Jazz"];
// push — adiciona ao final
generos.push("Metal");
console.log(generos); // ["Rock", "Pop", "Jazz", "Metal"]
// pop — remove o último
const ultimo = generos.pop();
console.log(ultimo); // "Metal"
console.log(generos); // ["Rock", "Pop", "Jazz"]
// indexOf — encontrar posição
console.log(generos.indexOf("Pop")); // 1
console.log(generos.indexOf("Funk")); // -1 (não existe)
// includes — verificar existência
console.log(generos.includes("Jazz")); // true
// join — montar uma string
console.log(generos.join(", ")); // "Rock, Pop, Jazz"
// slice — copiar trecho sem alterar original
const primeiros = generos.slice(0, 2);
console.log(primeiros); // ["Rock", "Pop"]
console.log(generos); // ["Rock", "Pop", "Jazz"] — intacto
Atenção ao que muta e ao que não muta:
push,pop,shift,unshift,spliceereversealteram o array original. Jásliceejoinnão alteram — retornam um novo valor. Saber essa diferença vai importar na Missão 4 da atividade.
5. Template Strings
Antes do ES6 (2015), para montar uma frase com variáveis era preciso concatenar com +:
const artista = "Queen";
const ano = 1975;
// jeito antigo
console.log("Artista: " + artista + ", ano: " + ano);
Isso funciona, mas fica difícil de ler conforme a frase cresce. Template strings resolvem isso: envolvem o texto em crases (`) e permitem inserir expressões JavaScript com ${}.
// jeito moderno
console.log(`Artista: ${artista}, ano: ${ano}`);
Qualquer expressão JS válida pode ir dentro de ${}:
const duracao = 354; // segundos
console.log(`Duração: ${Math.floor(duracao / 60)}min ${duracao % 60}s`);
// "Duração: 5min 54s"
Template strings também respeitam quebras de linha:
const card = `
Título: ${artista}
Ano: ${ano}
Duração: ${duracao}s
`;
console.log(card);
6. Funções
Uma função é um bloco de código com nome que pode ser chamado várias vezes. Funções existem no JavaScript desde o início, mas a forma de escrevê-las evoluiu.
O propósito central é reutilização: em vez de repetir a mesma lógica em 10 lugares, você escreve uma vez e chama pelo nome.
Declaração de função (function declaration)
A forma clássica, disponível desde ES1 (1997):
function saudar(nome) {
console.log(`Olá, ${nome}!`);
}
saudar("Ana"); // "Olá, Ana!"
saudar("Bruno"); // "Olá, Bruno!"
Funções com retorno
Nem toda função precisa imprimir algo — muitas vezes o objetivo é calcular e retornar um valor para ser usado em outro lugar. O return encerra a função e devolve o valor:
function duracaoEmMinutos(segundos) {
return Math.floor(segundos / 60);
}
const minutos = duracaoEmMinutos(354);
console.log(`${minutos} minutos`); // "5 minutos"
Diferença importante: uma função que usa
console.logimprime para você ver no console. Uma função que usareturndevolve o valor para quem chamou — esse valor pode ser guardado em uma variável ou usado em outro cálculo. As duas coisas podem coexistir numa mesma função, mas têm propósitos diferentes.
7. Arrow Functions
Arrow functions são uma sintaxe alternativa para escrever funções, introduzida no ES6 (2015). O nome vem do => que parece uma seta. Além de mais compactas, têm um comportamento diferente do this (detalhe avançado — não relevante agora).
Compare a mesma função escrita de três formas:
// Forma 1 — declaração clássica
function duracaoEmMinutos(segundos) {
return Math.floor(segundos / 60);
}
// Forma 2 — arrow function com bloco
const duracaoEmMinutos = (segundos) => {
return Math.floor(segundos / 60);
};
// Forma 3 — arrow compacta (retorno implícito, sem chaves)
const duracaoEmMinutos = (segundos) => Math.floor(segundos / 60);
As três fazem exatamente a mesma coisa. A forma compacta (sem {} e sem return) só funciona quando o corpo da função é uma única expressão.
Arrow functions são muito usadas como callback — funções passadas como argumento para outros métodos:
const playlist = [
{ titulo: "Bohemian Rhapsody", duracao: 354 },
{ titulo: "Imagine", duracao: 187 },
];
playlist.forEach((musica) => {
console.log(musica.titulo);
});
8. Spread
O operador spread (...) foi introduzido no ES6 (2015). O nome vem do inglês espalhar — ele “espalha” os itens de um array (ou propriedades de um objeto) em outro contexto.
Um uso muito comum é criar um novo array baseado em um existente, sem modificar o original:
const classicos = ["Bohemian Rhapsody", "Hotel California", "Imagine"];
const novaMusica = "Stairway to Heaven";
const playlistCompleta = [...classicos, novaMusica];
console.log(classicos.length); // 3 — original intacto
console.log(playlistCompleta.length); // 4
console.log(playlistCompleta);
// ["Bohemian Rhapsody", "Hotel California", "Imagine", "Stairway to Heaven"]
Comparando com push, que muta o array original:
// push — modifica o array existente
classicos.push(novaMusica);
console.log(classicos.length); // 4 — array original alterado!
// spread — cria um novo array, original preservado
const novaPlaylist = [...classicos, novaMusica];
O spread também funciona no meio do array e para combinar dois arrays:
const parte1 = ["Rock", "Pop"];
const parte2 = ["Jazz", "Metal"];
const todos = [...parte1, "Blues", ...parte2];
// ["Rock", "Pop", "Blues", "Jazz", "Metal"]
Resumo de referências
| Conceito | Onde pesquisar mais |
|---|---|
const e let | MDN — const · MDN — let |
var | MDN — var |
| Objetos | MDN — Objetos |
| Arrays | MDN — Array |
for...of | MDN — for…of |
| Template Strings | MDN — Template literals |
| Funções | MDN — Funções |
| Arrow Functions | MDN — Arrow functions |
| Spread | MDN — Spread syntax |