Variáveis e Tipos
Os fundamentos das variáveis modernas
JavaScript Moderno: Variáveis, Tipos e Estruturas de Dados
Neste tutorial, vamos explorar os fundamentos do JavaScript moderno: como declarar variáveis, entender os diferentes tipos de dados, manipular operadores e usar as estruturas de dados essenciais.
JavaScript é uma linguagem dinâmica e flexível que evoluiu consideravelmente desde sua criação. Com a chegada do ES6 (ECMAScript 2015) e das versões seguintes, a linguagem passou a oferecer recursos poderosos e modernos.
Declaração de variáveis
No JavaScript moderno, existem três formas de declarar variáveis:
let
let permite declarar variáveis cujo escopo é limitado ao bloco em que foram definidas:
let age = 25;
age = 26; // Reatribuição possível
if (true) {
let message = "Hello"; // Variável limitada a este bloco
console.log(message); // "Hello"
}
// console.log(message); // Erro: message não está definido
const
const permite declarar constantes cujo valor não pode ser reatribuído:
const PI = 3.14159;
// PI = 3.14; // Erro: não é possível reatribuir uma constante
const personne = { nom: "Alice" };
personne.nom = "Bob"; // Possível - é o conteúdo que pode mudar
// personne = {}; // Erro: não é possível reatribuir a referência
var (método antigo)
var era a única forma de declarar variáveis antes do ES6. Seu escopo é limitado à função ou global:
var x = 10;
var x = 20; // Redeclaração possível (problemático)
if (true) {
var y = 30; // Escopo não limitado ao bloco
}
console.log(y); // 30 - y é acessível aqui
Boas práticas
No JavaScript moderno, prefira:
constpor padrão para toda variável que não será reatribuídaletquando a reatribuição for necessária- Evite
var, a menos que você trabalhe com código legado
Tipos de dados
JavaScript é uma linguagem de tipagem dinâmica, o que significa que você não precisa declarar o tipo de uma variável.
Tipos primitivos
1. Number
JavaScript usa um único tipo para todos os números:
const entier = 42;
const decimal = 3.14;
const exponentiel = 2.5e5; // 250000
const binaire = 0b1010; // 10
const octal = 0o744; // 484
const hexadecimal = 0xFF; // 255
// Valores especiais
const infini = Infinity;
const pasUnNombre = NaN; // Not a Number
// Verificações
console.log(isNaN(pasUnNombre)); // true
console.log(isFinite(infini)); // false
2. String (cadeia de caracteres)
JavaScript oferece várias formas de criar strings:
// Aspas simples
const prenom = 'Marie';
// Aspas duplas
const nom = "Dupont";
// Template literals (crases) - ES6
const age = 30;
const message = `${prenom} ${nom} a ${age} ans.`;
// Métodos úteis
console.log(prenom.toUpperCase()); // MARIE
console.log(" texte ".trim()); // "texte"
console.log("abc,def".split(",")); // ["abc", "def"]
console.log("Hello".includes("ell")); // true
3. Boolean
const estMajeur = true;
const estInscrit = false;
// Expressões condicionais
const a = 5;
const b = 10;
console.log(a < b); // true
console.log(a === b); // false (igualdade estrita)
console.log(a >= 5); // true
4. Undefined
undefined representa uma variável declarada, mas sem valor atribuído:
let resultat;
console.log(resultat); // undefined
// Verificação
console.log(typeof resultat === 'undefined'); // true
5. Null
null representa a ausência deliberada de valor:
const donnees = null;
// Cuidado com a armadilha
console.log(typeof null); // "object" (bug histórico do JavaScript)
console.log(donnees === null); // true (use a igualdade estrita)
6. Symbol (ES6)
Symbol cria identificadores únicos e imutáveis:
const id1 = Symbol('id');
const id2 = Symbol('id');
console.log(id1 === id2); // false - cada Symbol é único
7. BigInt (ES2020)
Para representar inteiros de tamanho arbitrário:
const grandNombre = 1234567890123456789012345678901234567890n;
const autreFacon = BigInt("9007199254740991");
console.log(typeof grandNombre); // "bigint"
Tipos por referência (objetos)
1. Object
Objetos são coleções de pares chave-valor:
// Criação de objeto literal
const personne = {
prenom: "Jean",
nom: "Dupont",
age: 30,
adresse: {
ville: "Paris",
codePostal: "75001"
}
};
// Acesso às propriedades
console.log(personne.prenom); // "Jean"
console.log(personne["nom"]); // "Dupont"
// Adição/modificação de propriedades
personne.email = "jean.dupont@example.com";
personne.age = 31;
// Métodos de objetos
const cles = Object.keys(personne); // ["prenom", "nom", "age", "adresse", "email"]
const valeurs = Object.values(personne); // ["Jean", "Dupont", 31, {...}, "jean..."]
2. Array
Arrays são coleções ordenadas de valores:
// Criação de array
const fruits = ["pomme", "banane", "cerise"];
const mixte = [1, "deux", true, null, { clé: "valeur" }];
// Acesso aos elementos (indexados a partir de 0)
console.log(fruits[0]); // "pomme"
// Métodos úteis
fruits.push("orange"); // Adiciona no final
fruits.pop(); // Remove o último elemento
fruits.unshift("fraise"); // Adiciona no início
fruits.shift(); // Remove o primeiro elemento
// Laço forEach
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});
// Métodos de transformação (não modificam o array original)
const fruitsMajuscules = fruits.map(fruit => fruit.toUpperCase());
const fruitsCourts = fruits.filter(fruit => fruit.length < 6);
const total = [1, 2, 3, 4].reduce((acc, val) => acc + val, 0); // 10
3. Function
Em JavaScript, funções são objetos de primeira classe:
// Declaração de função
function saluer(nom) {
return `Bonjour, ${nom} !`;
}
// Expressão de função
const direAuRevoir = function(nom) {
return `Au revoir, ${nom} !`;
};
// Arrow function (ES6)
const multiplier = (a, b) => a * b;
// Função como parâmetro
function executerFonction(fn, valeur) {
return fn(valeur);
}
console.log(executerFonction(saluer, "Marie")); // "Bonjour, Marie !"
4. Date
const maintenant = new Date();
const dateSpecifique = new Date("2023-12-31T23:59:59");
const timestamp = dateSpecifique.getTime(); // milissegundos desde 1º de janeiro de 1970
5. Map e Set (ES6)
// Map - coleção de pares chave-valor (chaves de qualquer tipo)
const utilisateurs = new Map();
utilisateurs.set('u1', { nom: "Alice", age: 25 });
utilisateurs.set('u2', { nom: "Bob", age: 30 });
// Set - coleção de valores únicos
const nombres = new Set([1, 2, 3, 3, 4, 4, 5]); // {1, 2, 3, 4, 5}
Verificação de tipos
Para verificar o tipo de uma variável, use o operador typeof:
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof { a: 1 }); // "object"
console.log(typeof [1, 2, 3]); // "object" (arrays são objetos em JS)
console.log(typeof function() {}); // "function"
Para arrays, use Array.isArray():
console.log(Array.isArray([1, 2, 3])); // true
Conversão de tipos
JavaScript costuma fazer conversões implícitas, mas você também pode fazê-las explicitamente:
// Conversão para string
const num = 42;
const numStr = String(num); // "42"
const autreMethode = num.toString(); // "42"
// Conversão para número
const str = "42";
const strNum = Number(str); // 42
const parseMethode = parseInt(str, 10); // 42 (base 10)
const parseFloat = parseFloat("3.14"); // 3.14
// Conversão para booleano
const valeurBool = Boolean(1); // true
// false para: 0, "", null, undefined, NaN, false
Operadores
Operadores aritméticos
const a = 10;
const b = 3;
const addition = a + b; // 13
const soustraction = a - b; // 7
const multiplication = a * b; // 30
const division = a / b; // 3.3333...
const modulo = a % b; // 1 (resto da divisão)
const puissance = a ** b; // 1000 (ES2016)
// Incremento e decremento
let compteur = 0;
compteur++; // compteur = 1
compteur--; // compteur = 0
Operadores de comparação
const a = 10;
const b = "10";
// Igualdade (com conversão de tipo)
console.log(a == b); // true
// Igualdade estrita (sem conversão)
console.log(a === b); // false
// Desigualdade (com conversão)
console.log(a != b); // false
// Desigualdade estrita (sem conversão)
console.log(a !== b); // true
// Comparações
console.log(a > 5); // true
console.log(a <= 10); // true
Operadores lógicos
const x = true;
const y = false;
// E lógico
console.log(x && y); // false
// OU lógico
console.log(x || y); // true
// NÃO lógico
console.log(!x); // false
// Curto-circuito (útil para valores padrão)
const nom = null;
const nomAffiche = nom || "Utilisateur inconnu"; // "Utilisateur inconnu"
Operador de coalescência nula (ES2020)
const valeur = null;
const resultat = valeur ?? "Valeur par défaut"; // "Valeur par défaut"
// Diferente de || porque só usa o valor padrão se o valor for null ou undefined
Operador de encadeamento opcional (ES2020)
const utilisateur = {
profil: {
// adresse: { ville: "Paris" }
}
};
// Sem encadeamento opcional (risco de erro)
// const ville = utilisateur.profil.adresse.ville; // Erro!
// Com encadeamento opcional
const ville = utilisateur.profil?.adresse?.ville; // undefined
Operador de espalhamento (spread)
// Para arrays
const tab1 = [1, 2, 3];
const tab2 = [...tab1, 4, 5]; // [1, 2, 3, 4, 5]
// Para objetos
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
Desestruturação (ES6)
A desestruturação permite extrair valores de arrays ou objetos de forma concisa:
// Desestruturação de array
const nombres = [1, 2, 3, 4, 5];
const [premier, deuxieme, ...reste] = nombres;
console.log(premier); // 1
console.log(deuxieme); // 2
console.log(reste); // [3, 4, 5]
// Desestruturação de objeto
const personne = { prenom: "Alice", nom: "Dupont", age: 30 };
const { prenom, age, profession = "Inconnue" } = personne;
console.log(prenom); // "Alice"
console.log(age); // 30
console.log(profession); // "Inconnue" (valor padrão)
// Renomeação de propriedades
const { prenom: firstName } = personne;
console.log(firstName); // "Alice"
// Desestruturação aninhada
const utilisateur = {
id: 1,
infos: {
nom: "Durand",
contact: {
email: "durand@example.com"
}
}
};
const { infos: { contact: { email } } } = utilisateur;
console.log(email); // "durand@example.com"
Estruturas de controle
JavaScript oferece as estruturas de controle habituais, com algumas particularidades modernas.
Condicionais
// if, else if, else
const age = 18;
if (age < 18) {
console.log("Mineur");
} else if (age === 18) {
console.log("Tout juste majeur");
} else {
console.log("Majeur");
}
// Operador ternário
const statut = age >= 18 ? "majeur" : "mineur";
Laços
// for clássico
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// for...of (para iterar sobre os valores de um iterável)
const fruits = ["pomme", "banane", "cerise"];
for (const fruit of fruits) {
console.log(fruit);
}
// for...in (para iterar sobre as propriedades de um objeto)
const personne = { nom: "Dupont", prenom: "Jean", age: 30 };
for (const prop in personne) {
console.log(`${prop}: ${personne[prop]}`);
}
// while
let compteur = 0;
while (compteur < 5) {
console.log(compteur);
compteur++;
}
// do...while
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
Switch
const jour = "Lundi";
switch (jour) {
case "Lundi":
console.log("Début de semaine");
break;
case "Mercredi":
console.log("Milieu de semaine");
break;
case "Vendredi":
console.log("Fin de semaine");
break;
default:
console.log("Autre jour");
}
Entradas e saídas básicas
Console
// Exibição
console.log("Message simple");
console.info("Information");
console.warn("Avertissement");
console.error("Erreur");
// Exibição formatada
console.log("Nom: %s, Âge: %d", "Alice", 30);
// Agrupamento
console.group("Détails utilisateur");
console.log("Nom: Alice");
console.log("Âge: 30");
console.groupEnd();
// Tabela
console.table([
{ nom: "Alice", age: 25 },
{ nom: "Bob", age: 30 }
]);
// Medição de tempo
console.time("Timer");
// Operações demoradas...
console.timeEnd("Timer"); // Exibe o tempo decorrido
Interação com o usuário (navegador)
// Exibir uma mensagem
alert("Attention !");
// Pedir uma confirmação
const confirmation = confirm("Êtes-vous sûr ?");
if (confirmation) {
console.log("L'utilisateur a confirmé");
}
// Pedir uma entrada
const nom = prompt("Quel est votre nom ?", "Utilisateur");
console.log(`Bonjour, ${nom}`);
Exemplo completo
Aqui está um exemplo que usa vários conceitos que aprendemos:
// Programme qui calcule la moyenne d'une liste de nombres
// Définition d'une fonction fléchée pour calculer la moyenne
const calculerMoyenne = (nombres) => {
if (nombres.length === 0) return 0;
const somme = nombres.reduce((acc, val) => acc + val, 0);
return somme / nombres.length;
};
// Fonction pour comparer un nombre à la moyenne
const comparerAvecMoyenne = (nombre, moyenne) => {
if (nombre > moyenne) return "supérieur à";
if (nombre < moyenne) return "inférieur à";
return "égal à";
};
// Programme principal
try {
// Dans un environnement réel, ces valeurs pourraient venir d'une interface utilisateur
const nombres = [15, 20, 25, 10, 30];
// Afficher les nombres
console.log("Nombres:", nombres.join(", "));
// Calculer et afficher la moyenne
const moyenne = calculerMoyenne(nombres);
console.log(`La moyenne est: ${moyenne.toFixed(2)}`);
// Comparer chaque nombre à la moyenne
console.log("\nComparaison avec la moyenne:");
nombres.forEach((nombre, index) => {
const relation = comparerAvecMoyenne(nombre, moyenne);
console.log(`Nombre ${index + 1} (${nombre}) est ${relation} la moyenne.`);
});
// Filtrer les nombres supérieurs à la moyenne
const nombresSuperieurs = nombres.filter(nombre => nombre > moyenne);
console.log(`\nNombres supérieurs à la moyenne: ${nombresSuperieurs.join(", ")}`);
} catch (erreur) {
console.error("Une erreur est survenue:", erreur.message);
}
As principais diferenças em relação a outras linguagens
Se você já conhece outras linguagens de programação, aqui estão algumas diferenças notáveis em JavaScript:
-
Tipagem dinâmica: não é preciso declarar os tipos, eles são determinados em tempo de execução.
-
Função como objeto de primeira classe: as funções podem ser atribuídas a variáveis, passadas como argumentos e retornadas por outras funções.
-
Protótipos vs. classes: o JavaScript usa um sistema baseado em protótipos, embora a sintaxe de classes tenha sido introduzida no ES6.
-
Hoisting: as declarações de variáveis e funções são “elevadas” ao topo do seu escopo.
-
Eventos e callbacks: o JavaScript usa muito callbacks e promises para lidar com a assincronicidade.
-
Igualdade frouxa vs. estrita:
==realiza conversão de tipo,===não.
Boas práticas
Para escrever JavaScript moderno limpo e de fácil manutenção:
-
Use
constpor padrão,letse precisar reatribuir, e evitevar. -
Prefira arrow functions para funções curtas e callbacks.
-
Use a desestruturação para extrair valores de objetos ou arrays.
-
Aplique template literals para strings multilinha ou com interpolação.
-
Evite comparações frouxas (
==,!=), prefira comparações estritas (===,!==). -
Use parâmetros padrão e o operador spread/rest.
-
Adote os métodos modernos de array como
map,filterereduceno lugar dos laços tradicionais quando apropriado. -
Respeite a assincronicidade com Promises e async/await (que abordaremos em um próximo tutorial).
Exercícios práticos
Para consolidar seus conhecimentos, tente estes exercícios:
-
Escreva uma função que receba um array de números e retorne a soma dos números pares.
-
Crie um objeto representando um livro com propriedades como título, autor e um método para exibir essas informações.
-
Escreva uma função que receba uma string e retorne um objeto contendo o número de ocorrências de cada caractere.
-
Crie uma função que converta uma temperatura de Celsius para Fahrenheit ou vice-versa, de acordo com um parâmetro de modo.
-
Use a desestruturação para trocar os valores de duas variáveis sem usar uma variável temporária.
Conclusão
Neste tutorial, exploramos os fundamentos do JavaScript moderno:
- As diferentes formas de declarar variáveis (
let,const,var) - Os tipos de dados (primitivos e por referência)
- Os operadores (aritméticos, de comparação, lógicos)
- A desestruturação e os operadores spread/rest
- As estruturas de controle (condicionais e laços)
- As entradas/saídas básicas
Esses conceitos formam a base sobre a qual você construirá sua compreensão do JavaScript moderno. Conforme você avançar, descobrirá como esses elementos se combinam para criar aplicações web dinâmicas e interativas.
No próximo tutorial, exploraremos as funções modernas e seus novos recursos.
Precisa revisar o básico? Consulte nosso tutorial de introdução.
Pronto para continuar? Passe para o próximo tutorial sobre funções.
Comentários
Os comentários são alimentados pelo GitHub Discussions
Conecte-se com o GitHub para participar da discussão