- Arquitetura e Ecossistema JavaScript
JavaScript é uma linguagem de programação de tipagem dinâmica e fraca, padronizada pela especificação ECMAScript. A implementação completa da linguagem em ambientes web é composta por três pilares fundamentais:
- ECMAScript (ES): O núcleo da linguagem, definindo sintaxe, tipos, operadores e estruturas de controle.
- DOM (Document Object Model): A interface que permite a interação e manipulação de documentos HTML/XML.
- BOM (Browser Object Model): Objetos que permitem a interação com o navegador (como
window,location,history).
- Variáveis, Tipos de Dados e Operadores
Na evolução moderna do JavaScript, a declaração de variáveis deve priorizar let (para escopo de bloco e reatribuição) e const (para escopo de bloco e referência constante), evitando o uso de var devido aos seus problemas de hoisting e escopo de função.
Tipos Primitivos e Verificação
O JavaScript possui sete tipos primitivos. A verificação de tipos é frequentemente realizada através do operador typeof.
const analiseDeTipos = [42, "JavaScript", true, null, undefined, Symbol("id")];
analiseDeTipos.forEach(dado => {
// O typeof null retorna "object" devido a um bug histórico na linguagem
console.log(`Valor: ${String(dado)} | Tipo: ${typeof dado}`);
});
Operadores de Igualdade
Devido à tipagem fraca, o JavaScript realiza coerção de tipos ao usar os operadoers de igualdade (==) e diferença (!=). Para evitar comportamentos inesperados, utilize sempre os operadores de igualdade estrita (===) e diferança estrita (!==).
console.log(0 == "0"); // true (coerção de tipo)
console.log(0 === "0"); // false (sem coerção, tipos diferentes)
- Estruturas de Controle e Funções
As estruturas de controle permitem direcionar o fluxo de execução. Funções em JavaScript são objetos de primeira classe, podendo ser atribuídas a variáveis, passadas como argumentos ou retornadas por outras funções.
const filtrarNumerosPares = (numeros) => {
const resultado = [];
for (let i = 0; i < numeros.length; i++) {
if (numeros[i] % 2 === 0) {
resultado.push(numeros[i]);
}
}
return resultado;
};
const valores = [1, 2, 3, 4, 5, 6];
console.log(filtrarNumerosPares(valores)); // [2, 4, 6]
- Objetos Nativos e Manipulação de Coleções
Além dos primitivos, o JavaScript oferece objetos nativos poderosos. Arrays e Strings possuem métodos embutidos que facilitam a transformação de dados sem a necessidade de loops manuais.
const catalogo = [
{ produto: "Notebook", preco: 3500, estoque: 5 },
{ produto: "Mouse", preco: 150, estoque: 0 },
{ produto: "Teclado", preco: 250, estoque: 12 }
];
// Filtrar produtos disponíveis e mapear para uma lista de strings
const produtosDisponiveis = catalogo
.filter(item => item.estoque > 0)
.map(item => `${item.produto}: R$ ${item.preco}`);
console.log(produtosDisponiveis);
// ["Notebook: R$ 3500", "Teclado: R$ 250"]
- Manipulação do DOM (Document Object Model)
O DOM representa a página como uma árvore de nós. A seleção e modificação desses nós é a base da interatividade web. Métodos modernos como querySelector e querySelectorAll são preferíveis por aceitarem seletores CSS.
Criação e Inserção de Nós
const container = document.getElementById('lista-tarefas');
function adicionarTarefa(texto) {
const novoElemento = document.createElement('li');
novoElemento.textContent = texto;
novoElemento.classList.add('tarefa-item');
// Inserindo no final do container
container.appendChild(novoElemento);
}
Manipulação de Atributos e Estilos
const botao = document.querySelector('.btn-primario');
// Alterando classes
botao.classList.add('desabilitado');
botao.classList.remove('ativo');
// Alterando atributos e estilos inline
botao.setAttribute('aria-disabled', 'true');
botao.style.backgroundColor = '#cccccc';
- Sistema de Eventos e Propagação
Eventos são ações que ocorrem no navegador (cliques, teclas, carregamento). A abordagem moderna para vincular eventos é o método addEventListener, que permite múltiplos ouvintes e melhor controle sobre a fase de propagação.
Prevenção de Comportamento Padrão e Delegação
const formulario = document.getElementById('form-login');
formulario.addEventListener('submit', (evento) => {
// Impede o recarregamento da página
evento.preventDefault();
const usuario = evento.target.username.value;
if (usuario.length < 3) {
console.error("Usuário inválido");
return;
}
console.log("Submetendo dados de:", usuario);
});
// Delegação de eventos: ouvir o clique no pai para lidar com os filhos
const lista = document.getElementById('lista-dinamica');
lista.addEventListener('click', (evento) => {
if (evento.target.matches('.btn-excluir')) {
// Remove o elemento pai (o item da lista)
evento.target.parentElement.remove();
evento.stopPropagation(); // Impede que o evento suba para outros ancestrais
}
});
- Escopo e Cadeia de Escopo (Scope Chain)
O escopo determina a acessibilidade de variáveis. O JavaScript utiliza escopo léxico, o que singifica que a acessibilidade de uma variável é definida pela sua localização física no código fonte.
Escopo de Bloco vs. Escopo de Função
let variavelGlobal = "Acessível em todo o script";
function demonstrarEscopo() {
let variavelLocal = "Acessível apenas dentro da função";
if (true) {
let variavelDeBloco = "Acessível apenas dentro deste bloco if";
var variavelDeFuncao = "Ignora o bloco, pertence à função";
console.log(variavelDeBloco); // Funciona
}
// console.log(variavelDeBloco); // ReferenceError: não definida
console.log(variavelDeFuncao); // Funciona (var tem escopo de função)
}
// console.log(variavelLocal); // ReferenceError: não definida
A Cadeia de Escopo
Quando uma variável é referenciada, o motor do JavaScript a procura no escopo atual. Se não for encontrada, a busca sobe para o escopo pai, e assim sucessivamente até chegar ao escopo global. Essa sequência de buscas é chamada de Cadeia de Escopo.
const corExterna = "Azul";
function funcaoExterna() {
const corInterna = "Vermelho";
function funcaoInterna() {
const corMaisInterna = "Verde";
// Acessa a própria variável
console.log(corMaisInterna);
// Sobe na cadeia de escopo para encontrar a variável da função pai
console.log(corInterna);
// Sobe novamente até o escopo global
console.log(corExterna);
}
funcaoInterna();
}
funcaoExterna();