Configuração do Ambiente de Desenvolvimento
Para desenvolver em JavaScript, é comum criar arquivos HTML e JS localmente e executá-los no navegador. No entanto, limitações de segurança dos navegadores bloqueiam funcionalidades como requisições de rede em URLs com protocolo file://. Para garantir o funcionamento completo, utilize um servidor web local, acessando seu projeto via http:// ou https://.
Fundamentos da Sintaxe
JavaScript não obriga o uso de ponto e vírgula no final das instruções, pois o engine realiza inserção automática de semicolons (ASI). Contudo, adotar essa prática evita comportamentos inesperados. Expressões podem ser usadas como instruções independentes. Strings aceitam aspas simples (') ou duplas ("), blocos de código são delimitados por chaves ({}), e comentários seguem o padrão de linha (//) ou bloco (/* */). A linguagem diferencia maiúsculas de minúsculas.
Tipos de Dados e Operações
- Número: Unifica interios e ponto flutuante sob o tipo
Number. Valores especiais incluemNaN(resultado inválido),Infinity(overflow) e notação científica (3.14e2). Hexadecimais usam prefixo0x, e octais usam0o; no modo estrito ("use strict"), literais com zero à esquerda são proibidos para evitar ambiguidades. - Booleano: Representa valores lógicos
trueefalse. - Comparação: O opeardor
==aplica coerção de tipos, enquanto===verifica igualdade estrita (tipo e valor).NaNnão é igual a nenhum valor, nem a si mesmo; utilize a funçãoisNaN()para detecção. - BigInt: Suporta inteiros de precisão arbitrária, declarados com sufixo
n(ex:9007199254740991n) ou via construtorBigInt(). - Null e Undefined:
nullindica ausência intencional de valor, enquantoundefinedsinaliza variáveis não inicializadas. Prefiranullpara representar "vazio" explicitamente. - Array: Coleções ordenadas com colchetes, permitindo elementos de tipos mistos.
- Variáveis: Devem ser declaradas antes do uso.
varpossui escopo de função, enquantoleteconstintroduzem escopo de bloco, crucial para closures e loops.
Manipulação de Strings e Valores Nulos
Distinguir null e undefined é essencial para código robusto. Abordagens comuns incluem:
// Verificação abrangente (captura ambos)
if (valor == null) {
// Executa para null ou undefined
}
// Verificação específica
if (valor === undefined) {
// Apenas undefined
}
if (valor === null) {
// Apenas null
}
// Verificação segura com typeof (evita ReferenceError)
if (typeof valor === 'undefined') {
// Funciona mesmo para variáveis não declaradas
}
// Operadores modernos (ES2020+)
const valorPadrao = entrada ?? 'padrão'; // Atribui se null/undefined
const acessoSeguro = objeto?.chave?.subchave; // Encadeamento opcional
Erro Clássico: parseInt com map
Ao passar parseInt diretamente para map, o segundo argumento da callback (índice) é interpretado como base numérica, causando resultados inesperados.
const dados = ['5', '12', '1f'];
const resultadoIncorreto = dados.map(parseInt); // [5, NaN, NaN]
// Correções válidas:
const viaNumber = dados.map(Number); // [5, 12, NaN] (NaN para '1f')
const viaParseIntCorrigido = dados.map(str => parseInt(str, 10)); // [5, 12, 1]
const viaConversao = dados.map(str => +str); // [5, 12, NaN]
Closures em Loops: Let vs Var
A diferença entre let e var afeta closures em iterações. let cria um novo escopo por iteração, preservando o valor atual; var mantém uma referência compartilhada.
// Comportamento com let
function criarFuncoesComLet() {
const lista = [];
for (let contador = 1; contador <= 3; contador++) {
lista.push(() => contador ** 2);
}
return lista;
}
const funcsLet = criarFuncoesComLet();
console.log(funcsLet[0]()); // 1
console.log(funcsLet[1]()); // 4
console.log(funcsLet[2]()); // 9
// Comportamento com var
function criarFuncoesComVar() {
const lista = [];
for (var contador = 1; contador <= 3; contador++) {
lista.push(() => contador ** 2);
}
return lista;
}
const funcsVar = criarFuncoesComVar();
console.log(funcsVar[0]()); // 16 (valor final de contador: 4)
console.log(funcsVar[1]()); // 16
console.log(funcsVar[2]()); // 16
Geradores: Funções com Múltiplos Retornos
Geradores são funções especiais que podem pausar e retomar execução usando yield, permitindo a geração de sequências sob demanda.
function* sequenciaDeValores() {
yield 'início';
yield 'meio';
yield 'fim';
}
const iterador = sequenciaDeValores();
console.log(iterador.next().value); // 'início'
console.log(iterador.next().value); // 'meio'
Literais Numéricos e Acesso a Propriedades
Ao aplicar métodos em literais numéricos, o ponto pode ser confundido com separador decimal. Use parênteses ou duplo ponto para desambiguação.
// Causa erro de sintaxe:
// 123.toString();
// Soluções alternativas:
console.log(123..toString()); // "123"
console.log((123).toString()); // "123"
Expressões Regulares: Âncoras e Correspondência
As âncoras ^ e $ em regex definem início e fim da string, alterando a correspondência de parcial para exata.
const texto = 'Node.js';
console.log(/node/i.test(texto)); // true (correspondência parcial)
console.log(/^node$/i.test(texto)); // false (não é exatamente 'node')
Formatação de JSON com stringify
O terceiro parâmetro de JSON.stringify controla a indentação. Uma string como ' ' (dois espaços) habilita formatação legível com quebras de linha automáticas.
const configuracao = { tema: 'dark', versao: 2, plugins: ['a11y', 'seo'] };
const jsonFormatado = JSON.stringify(configuracao, null, ' ');
console.log(jsonFormatado);
// Saída:
// {
// "tema": "dark",
// "versao": 2,
// "plugins": [
// "a11y",
// "seo"
// ]
// }