
En ES5, nous déclarions des variables via var
.
Ces variables, ont une portée fonctionnelle, leur portée étant la plus proche des fonctions englobantes. Le comportement de var
peut donc être parfois déroutant. Voici un exemple :
var x = 5;
function func(randomize) {
if (randomize) {
var x = Math.random(); // portée: fonction entière
return x;
}
return x; // accède à la variable x de la ligne 4
}
func(false); // undefined
func(0); // undefined
Le fait que la fonction func()
retourne undefined
peut-être surprenant. On peut mieux comprendre pourquoi si on écrit le code afin de réfléter plus fidèlement ce qu'il se passe réellement :
var x = 5;
function func(randomize) {
var x;
if (randomize) {
x = Math.random();
return x;
}
return x;
}
func(false); // undefined
func(0); // undefined
Avec ES6, on peut également déclarer des variables via deux nouveaux mots-clés let
et const
. De telles variables ont une portée de bloc (voir la doc sur MDN), leurs portées sont les blocs les plus intérieurs. let
est à peu de chose près une version bloc de var
. const
fonctionne comme let
, mais crée des variables dont les valeurs ne peuvent pas être changées (constantes).
let
et const
se comportent plus strictement et émettent plus d'exceptions (par exemple, lorsque vous accédez à leurs variables dans leur portée avant qu'elles ne soient déclarées).
Lé délimitation de blocs permet de garder les effets des fragments de code plus locaux (voir ci-dessous). Ce comportement est plus courant que la portée de fonction, ce qui facilite la transition entre JavaScript et d'autres langages de programmation.
Si vous remplacez var par let dans la version initiale, vous obtenez un comportement différent :
let x = 5;
function func(randomize) {
if (randomize) {
let x = Math.random();
return x;
}
return x;
}
func(false); // 3
func(0); // 3
Les cas spéciaux des tableaux et des objets
Ces derniers ont un comportement un peu différent lorsqu'on les déclare avec const
. Leur contenu peut-être changé mais ils ne peuvent être réaffecté (on leur attribue comlétement une nouvelle valeur). Voyons quelques exemples :
Exemple 1 - affectation d'une nouvelle valeur à un entier :
const age = 18;
age = 20; // Va lever une exception
Ceci génère logiquement une erreur car la variable age
ne peut être ré-affecter.
Exemple 2 - Les tableaux
const ages = [18, 21, 16, 12];
ages.push(40);
console.log(ages); // [18, 21, 16, 12, 40];
ages = [18, 21, 40]; // génère une erreur
La constante ages
ligne 2 n'a pas été ré-affectée, il n'y a donc pas d'erreur, par contre, la ligne 6 en génère une.
Exemple 3 - Les objets
const person = {
name: 'Yann',
age: 40
};
person.age = 41;
console.log(person); // {name: "Yann", age: 41}
Comme vous le voyez, même comportement pour les objets, la valeur de la propriété age
de l'objet person
a pu être modifié sans erreur car l'objet person
n'a pas été intégralement modifié avec une nouvelle affectation de valeur.
Cela signifie que vous ne pouvez donc pas remplacer aveuglément var
par let
ou const
dans le code existant ; vous devez faire attention lors de la refactorisation. De même, déclarez vos variables de manière groupée et préalable.
Mon conseil est :
- - Préferez
const
. Vous pouvez l'utiliser pour toute les variables dont les valeurs ne changent jamais. - - Sinon, utilisez
let
pour les variables dont les valeurs changent. - - Evitez d'utiliser
var
désormais !
5