Const, réfractaire à tout changement ?

Es-tu réellement aussi rigide que tu le laisse paraître ?

Introduction

Au sein du langage de programmation JS existe actuellement trois manières différentes de déclarer des variables: var, let et const. Ce qui motive le choix d’un de ces trois mots clés réside en grande partie dans la portée que l’on souhaite donner à la variable . Néanmoins, const, est légèrement différent. En effet, on dit qu’une “constante” n’est plus modifiable par la suite. Mais est-ce vraiment le cas ?

Essayons aujourd’hui de décortiquer ensemble son comportement.

On va jouer selon tes règles

Le mot clé const va au-delà même de la considération de la portée que l’on souhaite offrir à une variable et donc à l’accessibilité de cette dernière dans le programme.

En effet, un autre élément est spécifié dans cette définition :

“(…) La valeur d’une constante ne peut être changée par réaffectation, et elle ne peut être déclarée de nouveau.“

C’est en effet cette seconde composante qui fait la particularité de ce mot clé par rapport à ses congénères. Le mot clé const restreint les actions possibles sur la valeur de la variable qui est déclarée.

Ne peut être changée par réaffectation

Premièrement, il ne permet pas de changer la valeur de la variable par réaffectation. Qu’est-ce que cela signifie du point de vue du comportement de cette variable et de sa valeur ?

Lorsque l’on décide d’affecter une valeur à une variable déclarée à l’aide du mot clé const, on ne peut alors le faire qu’à une seule reprise. Par la suite, il s’avère tout simplement impossible de renouveler cette opération d’affectation sur cette même variable en lui attribuant une nouvelle valeur.

// Ici, la variable pseudo voit sa valeur réaffecter
let pseudo = "Le Dev Novice";
pseudo = "Le Dev Presque Pro"; 

// Ici cependant, la réaffectation ne se fait pas
const dream = "Le Dev Infaillible";
dream = "Le Dev Génie"; // Uncaught TypeError: Assignment to constant variable.

Ne peut être déclarée de nouveau

Deuxièmement, le mot clé const ne permet pas au libellé utilisé pour déclarer la variable (on parle généralement d’identifiant ou identifier outre-manche) d’être réutilisé pour la déclaration d’une autre variable.

Cela signifie que le terme choisi pour décrire la variable, l’identifiant, qui va nous permettre de l’appeler au sein du programme pour récupérer sa valeur, sera unique.

const pseudo = "Le Dev Novice";
const pseudo = "Le Dev Presque Pro"; // Uncaught SyntaxError: Identifier 'pseudo' has already been declared"

let dream = "Le Dev Infaillible";
let dream = "Le Dev Génie"; // Uncaught SyntaxError: Identifier 'dream' has already been declared"

// Aucune erreur ici
var fake = "Le Dev Mytho";
var fake = "Le Dev Pipo";

Je veux la vérité !

Ainsi le mot clé const créé des contraintes pour ses variables et les valeurs qu’elles contiennent. Il n’autorise pas toutes les excentricités possibles et imaginables. Mais cela veut-il dire pour autant qu’il n’autorise absolument rien ? Que les valeurs contenues sont inchangeables de quelque manière que ce soit ?

La vérité, c’est que ce n’est pas le cas effectivement. S’il n’est que très peu permissif sur ce point, le mot clé const laisse quand même certaines modifications s’effectuer. Et cela est avant tout dû au type de données contenus dans les variables qu’il déclare.

Dans le langage de programmation JS existe effectivement ce que l’on pourrait caractériser comme deux familles de types: Les valeurs de types primitives et les valeurs de types objet.

C’est justement cette famille de type objet qui nous intéresse ici. Pourquoi cela ? Car ce type de donnée est sujet à un concept que l’on appelle la mutation.

Il est en train de muter

Ce qu’il faut bien comprendre ici c’est que toutes les valeurs de type primitives sont immuables. Autrement dit, elles ne peuvent être altérées. Une fois la valeur définie, elle ne peut être changée. Une variable peut se voir affecter une nouvelle valeur, mais celle-ci sera justement une autre valeur et non la modification de la valeur précédemment stockée.

Ce constat est différent pour ce qui est des valeurs de type objet. Définies en premier lieu avec une valeur précise, celles-ci peuvent alors se voir modifiées. On peut ajouter une nouvelle entité à un tableau ou ajouter une nouvelle paire clé-valeur à un objet. La valeur représentée par ce tableau ou cet objet est alors modifiée et non pas remplacée par une nouvelle valeur comme pour les types primitifs du langage.

let useless = ['Inari', 'Ondine', 'Robin', 'Jar Jar Binks'];


// On modifie la première entité du tableau useless
useless[0] = 'Stuart'; // ["Stuart", "Ondine", "Robin", "Jar Jar Binks"]

// On ajoute ensuite une nouvelle entité au tableau useless
useless.push('Pipin'); // ["Stuart", "Ondine", "Robin", "Jar Jar Binks", "Pipin"]

Ici, on a effectué des opérations de modification d’un tableau de base. On a modifié une de ses entités et on a ensuite ajouté une autre qui est venue se greffer à celles déjà existantes. Nous n’avons pas recréé un nouveau tableau dans la variable “useless”, nous avons seulement modifié celui déjà existant. On peut dire que l’on a effectué des opérations de mutation sur ce tableau.

Qu’est-ce qu’on const…ate ?

Et là je vous vois arriver sur vos grands claviers les ami(e)s codeurs ! Le questionnement s’empare peut être de vous. Très logiquement vous avez aperçu dans ce morceau de code que la variable n’est pas déclarée avec le mot clé const.

const useless = ['Inari', 'Ondine', 'Robin', 'Jar Jar Binks'];

// On ne peut affecter de nouveau cette variable car déclarée avec le mot clé const
useless = [];

// Modification du tableau useless existant → Aucune erreur renvoyée
useless[0] = 'Stuart'; // ["Stuart", "Ondine", "Robin", "Jar Jar Binks"]

// Modification du tableau useless existant → Aucune erreur renvoyée
useless.push('Pipin'); // ["Stuart", "Ondine", "Robin", "Jar Jar Binks", "Pipin"]

Mais c’est bel et bien là que réside la subtilité du mot clé const !

En effet, il accepte que des mutations soient réalisées sur des valeurs de types objet. Ainsi, on peut sans aucun problème le modifier à notre guise comme on l’aurait fait avec un tableau déclaré avec let ou var sans être restreint par le mot clé qu’est const.

Conclusion

Mon expérience toute relative du monde de la programmation fait que je ne saurais m’exprimer pour les autres langages, mais pour JS, mon impression est que la compréhension approximative de certains comportements sont parfois dû à des abus de langage subtils qui génèrent des erreurs dans notre conception.

Le mot clé const fait partie de ces possibles approximations. Parfois, on a tendance à imaginer const comme la déclaration de variable cloisonnant le concept de modification de valeur telle une vraie prison. Or, même si c’est le cas dans une certaine mesure, il est important selon moi de connaître son comportement lorsqu’il s’agit de sa relation avec le concept de mutation des valeurs de type objet.

Mais alors une autre question s’empare de mon esprit les ami(e)s codeurs… Connaissant désormais ce comportement, cela signifie-t-il qu’il faut éviter de déclarer des variables à l’aide du mot clé const pour les associer à des valeurs de type objet pour éviter ces mutations potentiellement fortuites ?