0%
JavaScript Moderne : Variables avec let et const

Variables et Types

Les fondamentaux des variables modernes

10-15 min

JavaScript Moderne : Variables, Types et Structures de données

Dans ce tutoriel, nous allons explorer les fondamentaux du JavaScript moderne : comment déclarer des variables, comprendre les différents types de données, manipuler les opérateurs et utiliser les structures de données essentielles.

JavaScript est un langage dynamique et flexible qui a considérablement évolué depuis sa création. Avec l’arrivée d’ES6 (ECMAScript 2015) et des versions suivantes, le langage offre désormais des fonctionnalités puissantes et modernes.

Déclaration de variables

En JavaScript moderne, il existe trois façons de déclarer des variables :

let

let vous permet de déclarer des variables dont la portée est limitée au bloc dans lequel elles sont définies :

let age = 25;
age = 26; // Réassignation possible

if (true) {
    let message = "Hello"; // Variable limitée à ce bloc
    console.log(message); // "Hello"
}
// console.log(message); // Erreur : message n'est pas défini

const

const permet de déclarer des constantes dont la valeur ne peut pas être réassignée :

const PI = 3.14159;
// PI = 3.14; // Erreur : impossible de réassigner une constante

const personne = { nom: "Alice" };
personne.nom = "Bob"; // Possible - c'est le contenu qui peut changer
// personne = {}; // Erreur : impossible de réassigner la référence

var (ancienne méthode)

var était la seule façon de déclarer des variables avant ES6. Sa portée est limitée à la fonction ou globale :

var x = 10;
var x = 20; // Redéclaration possible (problématique)

if (true) {
    var y = 30; // Portée non limitée au bloc
}
console.log(y); // 30 - y est accessible ici

Bonnes pratiques

En JavaScript moderne, préférez :

  • const par défaut pour toute variable qui ne sera pas réassignée
  • let lorsque la réassignation est nécessaire
  • Évitez var sauf si vous travaillez avec du code legacy

Types de données

JavaScript est un langage à typage dynamique, ce qui signifie que vous n’avez pas besoin de déclarer le type d’une variable.

Types primitifs

1. Number

JavaScript utilise un seul type pour tous les nombres :

const entier = 42;
const decimal = 3.14;
const exponentiel = 2.5e5; // 250000
const binaire = 0b1010; // 10
const octal = 0o744; // 484
const hexadecimal = 0xFF; // 255

// Valeurs spéciales
const infini = Infinity;
const pasUnNombre = NaN; // Not a Number

// Vérifications
console.log(isNaN(pasUnNombre)); // true
console.log(isFinite(infini)); // false

2. String (chaîne de caractères)

JavaScript offre plusieurs façons de créer des chaînes :

// Guillemets simples
const prenom = 'Marie';

// Guillemets doubles
const nom = "Dupont";

// Template literals (backticks) - ES6
const age = 30;
const message = `${prenom} ${nom} a ${age} ans.`;

// Méthodes utiles
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;

// Expressions conditionnelles
const a = 5;
const b = 10;
console.log(a < b); // true
console.log(a === b); // false (égalité stricte)
console.log(a >= 5); // true

4. Undefined

undefined représente une variable déclarée mais sans valeur assignée :

let resultat;
console.log(resultat); // undefined

// Vérification
console.log(typeof resultat === 'undefined'); // true

5. Null

null représente l’absence délibérée de valeur :

const donnees = null;

// Attention au piège
console.log(typeof null); // "object" (bug historique de JavaScript)
console.log(donnees === null); // true (utiliser l'égalité stricte)

6. Symbol (ES6)

Symbol crée des identifiants uniques et immuables :

const id1 = Symbol('id');
const id2 = Symbol('id');

console.log(id1 === id2); // false - chaque Symbol est unique

7. BigInt (ES2020)

Pour représenter des entiers de taille arbitraire :

const grandNombre = 1234567890123456789012345678901234567890n;
const autreFacon = BigInt("9007199254740991");
console.log(typeof grandNombre); // "bigint"

Types par référence (objets)

1. Object

Les objets sont des collections de paires clé-valeur :

// Création d'objet littéral
const personne = {
    prenom: "Jean",
    nom: "Dupont",
    age: 30,
    adresse: {
        ville: "Paris",
        codePostal: "75001"
    }
};

// Accès aux propriétés
console.log(personne.prenom); // "Jean"
console.log(personne["nom"]); // "Dupont"

// Ajout/modification de propriétés
personne.email = "jean.dupont@example.com";
personne.age = 31;

// Méthodes d'objets
const cles = Object.keys(personne); // ["prenom", "nom", "age", "adresse", "email"]
const valeurs = Object.values(personne); // ["Jean", "Dupont", 31, {...}, "jean..."]

2. Array

Les tableaux sont des collections ordonnées de valeurs :

// Création de tableau
const fruits = ["pomme", "banane", "cerise"];
const mixte = [1, "deux", true, null, { clé: "valeur" }];

// Accès aux éléments (indexés à partir de 0)
console.log(fruits[0]); // "pomme"

// Méthodes utiles
fruits.push("orange"); // Ajoute à la fin
fruits.pop(); // Supprime le dernier élément
fruits.unshift("fraise"); // Ajoute au début
fruits.shift(); // Supprime le premier élément

// Boucle forEach
fruits.forEach((fruit, index) => {
    console.log(`${index}: ${fruit}`);
});

// Méthodes de transformation (ne modifient pas le tableau 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

En JavaScript, les fonctions sont des objets de première classe :

// Déclaration de fonction
function saluer(nom) {
    return `Bonjour, ${nom} !`;
}

// Expression de fonction
const direAuRevoir = function(nom) {
    return `Au revoir, ${nom} !`;
};

// Fonction fléchée (ES6)
const multiplier = (a, b) => a * b;

// Fonction comme paramètre
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(); // millisecondes depuis le 1er janvier 1970

5. Map et Set (ES6)

// Map - collection de paires clé-valeur (clés de tout type)
const utilisateurs = new Map();
utilisateurs.set('u1', { nom: "Alice", age: 25 });
utilisateurs.set('u2', { nom: "Bob", age: 30 });

// Set - collection de valeurs uniques
const nombres = new Set([1, 2, 3, 3, 4, 4, 5]); // {1, 2, 3, 4, 5}

Vérification de types

Pour vérifier le type d’une variable, utilisez l’opérateur 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" (les tableaux sont des objets en JS)
console.log(typeof function() {}); // "function"

Pour les tableaux, utilisez Array.isArray() :

console.log(Array.isArray([1, 2, 3])); // true

Conversion de types

JavaScript effectue souvent des conversions implicites, mais vous pouvez également les faire explicitement :

// Conversion en chaîne
const num = 42;
const numStr = String(num); // "42"
const autreMethode = num.toString(); // "42"

// Conversion en nombre
const str = "42";
const strNum = Number(str); // 42
const parseMethode = parseInt(str, 10); // 42 (base 10)
const parseFloat = parseFloat("3.14"); // 3.14

// Conversion en booléen
const valeurBool = Boolean(1); // true
// false pour: 0, "", null, undefined, NaN, false

Opérateurs

Opérateurs arithmétiques

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 (reste de la division)
const puissance = a ** b; // 1000 (ES2016)

// Incrémentation et décrémentation
let compteur = 0;
compteur++; // compteur = 1
compteur--; // compteur = 0

Opérateurs de comparaison

const a = 10;
const b = "10";

// Égalité (avec conversion de type)
console.log(a == b); // true

// Égalité stricte (sans conversion)
console.log(a === b); // false

// Inégalité (avec conversion)
console.log(a != b); // false

// Inégalité stricte (sans conversion)
console.log(a !== b); // true

// Comparaisons
console.log(a > 5); // true
console.log(a <= 10); // true

Opérateurs logiques

const x = true;
const y = false;

// ET logique
console.log(x && y); // false

// OU logique
console.log(x || y); // true

// NON logique
console.log(!x); // false

// Court-circuit (utile pour des valeurs par défaut)
const nom = null;
const nomAffiche = nom || "Utilisateur inconnu"; // "Utilisateur inconnu"

Opérateur de coalescence nulle (ES2020)

const valeur = null;
const resultat = valeur ?? "Valeur par défaut"; // "Valeur par défaut"
// Différent de || car il n'utilise la valeur par défaut que si la valeur est null ou undefined

Opérateur de chaînage optionnel (ES2020)

const utilisateur = {
    profil: {
        // adresse: { ville: "Paris" }
    }
};

// Sans chaînage optionnel (risque d'erreur)
// const ville = utilisateur.profil.adresse.ville; // Erreur !

// Avec chaînage optionnel
const ville = utilisateur.profil?.adresse?.ville; // undefined

Opérateur de décomposition (spread)

// Pour les tableaux
const tab1 = [1, 2, 3];
const tab2 = [...tab1, 4, 5]; // [1, 2, 3, 4, 5]

// Pour les objets
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }

Déstructuration (ES6)

La déstructuration permet d’extraire des valeurs de tableaux ou d’objets de manière concise :

// Déstructuration de tableau
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]

// Déstructuration d'objet
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" (valeur par défaut)

// Renommage de propriétés
const { prenom: firstName } = personne;
console.log(firstName); // "Alice"

// Déstructuration imbriquée
const utilisateur = {
    id: 1,
    infos: {
        nom: "Durand",
        contact: {
            email: "durand@example.com"
        }
    }
};
const { infos: { contact: { email } } } = utilisateur;
console.log(email); // "durand@example.com"

Structures de contrôle

JavaScript offre les structures de contrôle habituelles avec quelques particularités modernes.

Conditionnels

// 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");
}

// Opérateur ternaire
const statut = age >= 18 ? "majeur" : "mineur";

Boucles

// for classique
for (let i = 0; i < 5; i++) {
    console.log(i); // 0, 1, 2, 3, 4
}

// for...of (pour itérer sur les valeurs d'un itérable)
const fruits = ["pomme", "banane", "cerise"];
for (const fruit of fruits) {
    console.log(fruit);
}

// for...in (pour itérer sur les propriétés d'un objet)
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");
}

Entrées et sorties de base

Console

// Affichage
console.log("Message simple");
console.info("Information");
console.warn("Avertissement");
console.error("Erreur");

// Affichage formaté
console.log("Nom: %s, Âge: %d", "Alice", 30);

// Groupage
console.group("Détails utilisateur");
console.log("Nom: Alice");
console.log("Âge: 30");
console.groupEnd();

// Tableau
console.table([
    { nom: "Alice", age: 25 },
    { nom: "Bob", age: 30 }
]);

// Mesure du temps
console.time("Timer");
// Opérations longues...
console.timeEnd("Timer"); // Affiche le temps écoulé

Interaction avec l’utilisateur (navigateur)

// Afficher un message
alert("Attention !");

// Demander une confirmation
const confirmation = confirm("Êtes-vous sûr ?");
if (confirmation) {
    console.log("L'utilisateur a confirmé");
}

// Demander une entrée
const nom = prompt("Quel est votre nom ?", "Utilisateur");
console.log(`Bonjour, ${nom}`);

Exemple complet

Voici un exemple qui utilise plusieurs concepts que nous avons appris :

// 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);
}

Les différences clés avec d’autres langages

Si vous connaissez d’autres langages de programmation, voici quelques différences notables en JavaScript :

  1. Typage dynamique : Pas besoin de déclarer les types, ils sont déterminés à l’exécution.

  2. Fonction comme objet de première classe : Les fonctions peuvent être assignées à des variables, passées comme arguments et retournées par d’autres fonctions.

  3. Prototypes vs Classes : JavaScript utilise un système basé sur les prototypes, bien que la syntaxe des classes ait été introduite en ES6.

  4. Hoisting : Les déclarations de variables et de fonctions sont “hissées” en haut de leur portée.

  5. Événements et callback : JavaScript utilise beaucoup les callbacks et les promesses pour gérer l’asynchronicité.

  6. Égalité lâche vs stricte : == effectue une conversion de type, === ne le fait pas.

Bonnes pratiques

Pour écrire du JavaScript moderne propre et maintenable :

  1. Utilisez const par défaut, let si vous avez besoin de réassigner, et évitez var.

  2. Préférez les fonctions fléchées pour les fonctions courtes et les callbacks.

  3. Utilisez la déstructuration pour extraire des valeurs d’objets ou de tableaux.

  4. Appliquez les template literals pour les chaînes multilignes ou avec interpolation.

  5. Évitez les comparaisons lâches (==, !=), préférez les comparaisons strictes (===, !==).

  6. Utilisez les paramètres par défaut et les opérateurs de décomposition.

  7. Adoptez les méthodes modernes de tableau comme map, filter, reduce au lieu des boucles traditionnelles quand c’est approprié.

  8. Respectez l’asynchronicité avec les Promises et async/await (que nous aborderons dans un prochain tutoriel).

Exercices pratiques

Pour solidifier vos connaissances, essayez ces exercices :

  1. Écrivez une fonction qui prend un tableau de nombres et retourne la somme des nombres pairs.

  2. Créez un objet représentant un livre avec des propriétés comme le titre, l’auteur, et une méthode pour afficher ces informations.

  3. Écrivez une fonction qui prend une chaîne et retourne un objet contenant le nombre d’occurrences de chaque caractère.

  4. Créez une fonction qui convertit une température de Celsius en Fahrenheit ou inversement, selon un paramètre de mode.

  5. Utilisez la déstructuration pour échanger les valeurs de deux variables sans utiliser de variable temporaire.

Conclusion

Dans ce tutoriel, nous avons exploré les fondamentaux du JavaScript moderne :

  • Les différentes façons de déclarer des variables (let, const, var)
  • Les types de données (primitifs et par référence)
  • Les opérateurs (arithmétiques, de comparaison, logiques)
  • La déstructuration et les opérateurs de décomposition
  • Les structures de contrôle (conditionnelles et boucles)
  • Les entrées/sorties de base

Ces concepts constituent les fondements sur lesquels vous construirez votre compréhension du JavaScript moderne. À mesure que vous progresserez, vous découvrirez comment ces éléments s’assemblent pour créer des applications web dynamiques et interactives.

Dans le prochain tutoriel, nous explorerons les fonctions modernes et leurs nouvelles fonctionnalités.


Besoin de revoir les bases ? Consultez notre tutoriel d’introduction.

Prêt à continuer ? Passez au prochain tutoriel sur les fonctions.

Commentaires

Les commentaires sont alimentés par GitHub Discussions

Connectez-vous avec GitHub pour participer à la discussion

Lien copié !