Back

Déclarations de variables JavaScript : Comprendre var, let et const

Déclarations de variables JavaScript : Comprendre var, let et const

Le développement JavaScript moderne exige de la clarté dans les déclarations de variables JavaScript—pourtant, de nombreux développeurs peinent encore à choisir entre var, let et const. Comprendre la portée des variables ES6 ne consiste pas simplement à mémoriser des règles ; il s’agit d’écrire du code qui communique l’intention et prévient les bugs avant qu’ils ne surviennent.

Points clés à retenir

  • La portée de bloc (let/const) offre un meilleur confinement des variables que la portée de fonction (var)
  • La Zone Morte Temporelle empêche l’utilisation des variables avant leur initialisation
  • const empêche la réaffectation mais pas la mutation des objets et tableaux
  • Le JavaScript moderne privilégie const par défaut, let si nécessaire, et évite var

Comprendre les trois mots-clés de déclaration JavaScript

JavaScript offre trois façons de déclarer des variables, chacune avec des comportements distincts concernant la portée, le hoisting et la réaffectation. Votre choix signale différentes intentions à la fois au moteur JavaScript et aux autres développeurs qui lisent votre code.

Portée de bloc vs portée de fonction

La différence fondamentale entre la portée des variables ES6 moderne et les modèles hérités réside dans la façon dont les variables sont confinées :

function processData() {
    if (true) {
        var x = 1;  // Function-scoped
        let y = 2;  // Block-scoped
        const z = 3; // Block-scoped
    }
    console.log(x); // 1 (accessible)
    console.log(y); // ReferenceError
    console.log(z); // ReferenceError
}

Avec var, les variables s’échappent des blocs mais restent dans les fonctions. let et const respectent tous deux les limites de bloc—toute accolade crée une nouvelle portée, y compris celles des boucles, des conditionnelles et des blocs simples.

La Zone Morte Temporelle expliquée

Les déclarations de variables JavaScript avec let et const sont remontées (hoisted) mais restent non initialisées jusqu’à ce que leur déclaration soit atteinte. Cela crée la Zone Morte Temporelle (Temporal Dead Zone ou TDZ) :

console.log(myVar);   // undefined (hoisted, initialized)
console.log(myLet);   // ReferenceError (TDZ)
console.log(myConst); // ReferenceError (TDZ)

var myVar = 1;
let myLet = 2;
const myConst = 3;

La TDZ prévient les bugs subtils que le comportement de var causait souvent. Vous ne pouvez pas utiliser accidentellement une variable avant qu’elle ne soit correctement initialisée—le moteur lève immédiatement une erreur.

Réaffectation vs mutation

Une distinction critique que de nombreux développeurs manquent : const empêche la réaffectation, pas la mutation :

const user = { name: 'Alice' };
user.name = 'Bob';          // Allowed (mutation)
user = { name: 'Charlie' }; // TypeError (reassignment)

const scores = [95, 87];
scores.push(91);            // Allowed
scores = [100, 100];        // TypeError

Pour une véritable immutabilité, combinez const avec Object.freeze() ou des bibliothèques de données immutables. Le mot-clé de déclaration seul ne rend pas vos données immutables—il rend la liaison immutable.

Bonnes pratiques modernes pour les déclarations de variables

Les bases de code JavaScript actuelles suivent une hiérarchie claire :

  1. const par défaut : À utiliser pour les valeurs qui ne seront pas réaffectées. Cela inclut la plupart des variables, même les objets et tableaux que vous allez muter.

  2. Utiliser let pour la réaffectation : Compteurs de boucle, variables d’accumulation et valeurs qui nécessitent réellement une nouvelle liaison.

  3. Éviter var dans le nouveau code : Il n’existe aucun cas d’usage moderne où var offre des avantages par rapport à let.

L’outillage moderne applique ces modèles. La règle no-var d’ESLint et la règle prefer-const détectent automatiquement les violations. TypeScript traite les règles de portée des variables ES6 comme fondamentales, faisant de la portée de bloc le modèle mental par défaut.

Considérations relatives aux frameworks

Les hooks React dépendent d’un comportement prévisible des déclarations de variables JavaScript :

function Counter() {
    const [count, setCount] = useState(0); // const for the binding
    
    // Wrong: Can't reassign
    // count = count + 1;
    
    // Right: Use the setter
    setCount(count + 1);
}

L’API de composition de Vue et d’autres frameworks modernes suivent des modèles similaires, où const domine car les systèmes de réactivité gèrent les mises à jour via des méthodes, et non par réaffectation.

Pourquoi le code hérité utilise encore var

Vous rencontrerez var dans les bases de code plus anciennes pour des raisons historiques. Avant ES6 (2015), c’était la seule option. La migration nécessite des tests minutieux car :

  • Changer var en let dans les boucles peut corriger des bugs ou en introduire, selon le comportement des closures
  • Certains codes hérités exploitent délibérément le hoisting de portée de fonction de var
  • Les outils de build plus anciens peuvent ne pas transpiler correctement la portée des variables ES6

Lors du refactoring, utilisez des outils automatisés comme jscodeshift avec une couverture de tests complète. Ne convertissez pas manuellement des milliers de déclarations—laissez l’outillage gérer les changements mécaniques pendant que vous vérifiez le comportement.

Conclusion

Les déclarations de variables JavaScript dans le code moderne suivent une règle simple : utilisez const par défaut, let lorsque vous avez besoin de réaffectation, et jamais var. Il ne s’agit pas de suivre les tendances—il s’agit d’écrire du code qui exprime clairement l’intention et exploite la portée des variables ES6 pour prévenir des catégories entières de bugs. La Zone Morte Temporelle, la portée de bloc et les règles de réaffectation ne sont pas des obstacles—ce sont des garde-fous qui vous guident vers un JavaScript plus maintenable.

FAQ

Oui, const empêche uniquement la réaffectation de la variable elle-même, pas la modification du contenu. Vous pouvez ajouter, supprimer ou modifier des propriétés dans les objets et des éléments dans les tableaux déclarés avec const. La variable pointe toujours vers le même objet ou tableau en mémoire.

Vous obtiendrez une ReferenceError en raison de la Zone Morte Temporelle. Contrairement à var qui retourne undefined lorsqu'on y accède avant la déclaration, les variables let et const existent dans un état non initialisé jusqu'à ce que le code atteigne leur ligne de déclaration.

Seulement avec des tests minutieux. Bien que généralement bénéfique, changer var en let dans les boucles peut altérer le comportement des closures. Utilisez des outils de refactoring automatisés avec une couverture de tests complète plutôt que des changements manuels pour éviter d'introduire des bugs.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay