Informatique


Affectation par valeur, par adresse, var, let et const


Principe

  1. Pour les types primitifs:
    • On utilisera var ou let pour la variable, dont la valeur évolue durant l'exécution du scope au sein duquel elle est visible.
    • On utilisera const pour la variable, dont la valeur doit rester constante tout au long de l'exécution du scope au sein duquel elle est visible.
  2. Pour les types objets:
    • On utilisera toujours const pour une variable de type objet car ce type de variables est affecté par adresse.


Les types primitifs

Il en existe 3 (en fait 6 mais 3 seulement sont ici visés):

  • String
  • Number
  • Boolean

Une variable peut changer de type dynamiquement, il suffit de lui réaffecter une valeur d'un autre type, on dit que JavaScript est faiblement typé.

Les types primitifs sont des types qui sont systématiquement passés par valeur où que l'on se trouve dans le code


Les variables déclarées au moyen des constructeurs String(), Number() et Boolean() seront aussi passées par valeurs.

Avec var

Démo
<h2>Déclaration avec var</h2>
	var cours1, cours2;
	cours1=new String("Logique");
	cours2 = cours1;
	document.write(cours2); //Affiche Logique
	cours1="PHP";
	document.write(cours1); //Affiche PHP
	document.write(cours2); //Affiche Logique

Quand une variable est déclarée avec var:

  • on peut réaffecter la variable
  • on peut redéclarer la variable (même dans le même scope)
  • pas d'obligation d'initialisation
  • locale uniquement si déclarée dans le bloc d'une fonction
  • création d'une variable globale si utilisée dans le scope window

Avec let
Démo
<h2>Déclaration avec let</h2>
	{
	let val1 = 1;
	{
		let val2 = 2;
		console.log(val1);// renvoie: 1
		console.log(val2); // renvoie: 2
		{
			let val3=3;
				console.log(val1);// renvoie: 1
				console.log(val2); // renvoie: 2
				console.log(val3); // renvoie: 3
		}
	}
console.log(val1);// renvoie: 1	
console.log(val2);// renvoie Referencerror
console.log(val3);// renvoie Referencerror
}

Quand une variable est déclare avec let:

  • on peut réaffecter la variable
  • on ne peut pas redéclarer la variable dans le même scope
  • pas d'obligation d'initialisation
  • locale au bloc où elle a été déclarée
  • pas de création d'une variable globale même si déclarée dans le scope de window

Avec const
Démo
	const maconstA= 36;
	console.log(maconstA);
	/*Les lignes suivantes lèvent une erreur
	maconstA=72;
	console.log(maconstA);

	const maconstA=89;
	console.log(maconstA);*/

Quand une variable est déclarée avec const:

  • on ne peut pas réaffecter la variable
  • on ne peut pas redéclarer la variable dans le même scope
  • une constante doit être initialisée au moment de sa création
  • locale au bloc où elle a été déclarée
  • pas de création d'une variable globale même si déclarée dans le scope de window
  • une variable déclarée avec var ou let peut porter le même nom qu'une constante appartenant au même bloc ou à la même fonction


Utiliser les caractéristiques de let

Démo
	for(var i=0;i<10;i++){
		setTimeout(function(){document.write(i)},1000);
	}

JS est asynchrone, c'est l'interpréteur qui ordonne les instructions à effectuer afin que l'exécution des instructions soit la plus rapide: il incrémente d'abord le compteur i et exécute ensuite 10 fois l'affichage (après 1sec) avec la valeur 10!

Démo
	for(let i=0;i<10;i++){
		setTimeout(function(){document.write(i)},1000);
	}

C'est la même chose avec let, à un détail près: la variable i est détruite à la fin de chaque tour de boucle, ce qui n'est pas le cas avec var (sauf si var est utilisé dans une fonction!).
L'interpréteur est donc obligé de mémoriser l'état de i à chaque tour pour ensuite exécuté 10 fois l'affichage!


Le type objet

Tous les autres types sont des objets:

  • Array
  • Date
  • Object
  • function (...et oui les fonctions sont aussi des objets en JS)

Exemple: passage par référence

Démo
<h2>Affectation par un objet</h2>
<script>
	var cours1, cours2;
	cours1={nom:"Logique"};
	cours2 = cours1;
	document.write(cours2.nom); //Affiche Logique
	cours1.nom="PHP";
	document.write(cours1.nom); //Affiche PHP
	document.write(cours2.nom); //Affiche PHP
</script>

Dans l'exemple c'est l'adresse de cours1 qui est affectée à cours2.
Dorénavant dans cours2 on trouve une adresse qui "pointe" vers la variable cours1.

Le types objet est un type systématiquement passé par référence où que l'on se trouve dans le code.


Une variable affectée par une adresse est un pointeur car "elle pointe" vers la variable dont elle contient l'adresse.

const permet de protéger les variables de type object en empêchant le risque d'écrasement de leur référence.


Les objets sont passés par référence et pas par valeur, on peut donc modifier l'objet comme on veut car on ne touche pas à sa référence. I

Les tableaux et les objets sont passés par référence (par adresse), il est donc très important de veiller à ce que ces références (ou adresses) soient protégées et donc qu'elles ne risquent pas d'être écrasées pendant le déroulement du script.
On pourra donc toujours faire évoluer le tableau ou l'objet mais on ne risquera pas de supprimer sa référence par erreur.

Démo
	const eleve=["Desproges"];
	//On fait évoluer eleve
	eleve.push("Perret","Neymar","balathazar");
	console.log(eleve);
	//On tente d'écraser la référence eleve
	eleve=["plouc"];

La dernière instruction de l'exemple provoque une erreur car on tente d'écraser la référence de la constante eleve.


Quiz

var, let et const 1