0%
JavaScript Moderno: Variáveis com let e const

Variáveis e Tipos

Os fundamentos das variáveis modernas

10-15 min

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:

  • const por padrão para toda variável que não será reatribuída
  • let quando 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:

  1. Tipagem dinâmica: não é preciso declarar os tipos, eles são determinados em tempo de execução.

  2. 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.

  3. Protótipos vs. classes: o JavaScript usa um sistema baseado em protótipos, embora a sintaxe de classes tenha sido introduzida no ES6.

  4. Hoisting: as declarações de variáveis e funções são “elevadas” ao topo do seu escopo.

  5. Eventos e callbacks: o JavaScript usa muito callbacks e promises para lidar com a assincronicidade.

  6. 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:

  1. Use const por padrão, let se precisar reatribuir, e evite var.

  2. Prefira arrow functions para funções curtas e callbacks.

  3. Use a desestruturação para extrair valores de objetos ou arrays.

  4. Aplique template literals para strings multilinha ou com interpolação.

  5. Evite comparações frouxas (==, !=), prefira comparações estritas (===, !==).

  6. Use parâmetros padrão e o operador spread/rest.

  7. Adote os métodos modernos de array como map, filter e reduce no lugar dos laços tradicionais quando apropriado.

  8. 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:

  1. Escreva uma função que receba um array de números e retorne a soma dos números pares.

  2. Crie um objeto representando um livro com propriedades como título, autor e um método para exibir essas informações.

  3. Escreva uma função que receba uma string e retorne um objeto contendo o número de ocorrências de cada caractere.

  4. Crie uma função que converta uma temperatura de Celsius para Fahrenheit ou vice-versa, de acordo com um parâmetro de modo.

  5. 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

Link copiado!