Programmation Javascript (NFA041)

Bases de programmation illustrées en javascript,

Les Tableaux (1)

Olivier Pons
(olivier.pons@lecnam.net)

2022

Les tableaux (Array)

Le moyen le plus simple de représenter une collection de valeur.

Ils représentent une séquence finie d'éléments auxquels on peut accéder par leur position, ou indice, dans la séquence.

let  tab= []; // Création du tableau (vide)
undefined
> tab[0]="zero"  //ajout dans la premiere case
'zero'           //d'indice 0
> tab[1]="un"   //ajout dans la case d'indice 1
'un'
> tab[2]="deux"
'deux'
> tab
[ 'zero', 'un', 'deux' ]
>  
> tab[5]="cinq"
'cinq'
> tab
[ 'zero', 'un', 'deux', <2 empty items>, 'cinq' ]
> 
> let tab2=["il","fait","beau"]
undefined
> tab2
[ 'il', 'fait', 'beau' ]
> 
> tab[1]+" et "+tab[2]
'un et deux'
> tab[2].toUpperCase()
'DEUX'
> 
> tab[4]
undefined
> tab[10]
undefined
> tab[10]===undefined
true
> tab.length
6
> tab2.length
3
tab2[tab2.> tab2[tab2.length-1]
'beau'
> 

Attention

> tab2[tab2.length]  //toujours undefined
undefined            // a l'indice length on est trop loin
                     // car on commence à 0 donc le dernier 
                     //est a length-1

Parcourir les tableaux

Avec des boucles (for, while,...)

Exemple : la somme des éléments (avec for)

> let tab3=[1,4,8,10,12] 
undefined
> let s= 0;
undefined
// on fait la somme des element de tab3
> for (i= 0; i < tab3.length; i++) {
...     s= s + tab3[i];
...    }
35
> s
35
> 

Exemple : concatenation des éléments (avec while)

> let tab4=[1,2,3,"nous","irons","au","bois"] 
undefined
> let s2= "";
undefined
> let i=0;
undefined
//concatène les element tab4 
//les nombre sont implicitement convertis en chaîne
> while(i<tab4.length){
 s2=s2+" "+tab4[i];
 i++;
}   ^
6 //valeur de i
> s2
' 1 2 3 nous irons au bois'
> 

Parcourir les tableaux

Avec des fonctions recursives

Exemple : la somme des éléments

let tabNum=[2,4,6,8,10];
function sommeAux(t,n){
  if (n<0) {
    return 0
  }else{
    return t[n]+sommeAux(t,n-1);
  }
}
function somme(t){return sommeAux(t,t.length-1)}
> somme(tabNum)
30

On verra des méthodes spécifiques plus tard après avoir vu les objets et les fonctions d'ordre supérieure

Tableaux, comparaison, mémoire...

Définissons d'abord une constante et une variables contenant des nombres

const maC1=9.8;
let maVar1=33;

En gardant la métaphore de la boite, la representation en mémoire peut se schématiser

Les boites contiennent les valeurs associés à maC1 et maVar1

Définissons maintenant deux constantes ayant pour valeur des tableaux qui ont les même elements

const t1=[1,2,3];
const t2=[1,2,3];

comparons les avec nos opérateurs de comparaison:

> t1===t2
false
> t1==t2
false
> 

Il ne sont pas égaux !

A la difference des valeurs vues jusqu'ici, la valeur d'un tableau est une référence à une zone mémoire.

Si on garde la métaphore de la boite introduite dans la partie variable. Pour les types de base la boite contient directement une valeur de type number,bool,...

t1 et t2 contiennent des references vers des zones mémoire différentes

Notons que pour les même raisons

> [1,2,3] === [1,2,3] // les 2 collections de valeurs (tableaux)
false                 // contiennent bien les même valeurs
                      // mais sont situé  dans des zones mémoire différentes
> [1,2,3] == [1,2,3]
false
> 

Essayons de modifier la constante t1

> t1=2;
Uncaught TypeError: Assignment to constant variable.

C'est une constante donc l’interpréteur javascript refuse.
On ne peut donc pas changer la référence à la zone mémoire

Mais on peut modifier ce qu'il y a dans la zone mémoire elle même La notation t1[1] suit la référence en se position sur la case seconde case (indice 1). On peut alors lire la valeur dans la case ou la modifier.

> t1[1]=99
99
> console.log(t1)
[ 1, 99, 3 ]
undefined

t1 contient la meme référence, mais le contenu de la seconde case a été modifié

avec des variables

let t3=[4,5,6];
let t4=[4,5,6];

là encore ils sont différent :

> t3===t4;
false
> t3==t4;
false

car ils désignent 2 zones mémoire différentes

t3 et t2 référencent des zones mémoire différentes

On peut comme précédemment modifier une case:

t3[0]=7;

On aura alors

> t3
[ 7, 5, 6 ]

et en mémoire :

la première case de t3 est modifiée

mais on peut aussi modifier t4 pour qu'il référence autre chose

t4=[0,0,0,0,7];

on à alors

> t4
[ 0, 0, 0, 0, 7 ]

t4 référence une nouvelle zone mémoire

L'ancienne zone mémoire référencé par t4 est toujours là mais n'est plus accessible , elle sera nettoyé (c'est à dire que la mémoire pourra être utiliser par le système quand on créera de nouveaux objets ). Le mécanisme de nettoyage automatique s'appelle un ramasse miettes (en anglais on parle de GC Garbage collection).

Enfin on peut aussi affecter à t4 la référence contenue dans t3

t4=t3

Maintenant les 2 tableaux désigne la meme zone mémoire, on a :

les 2 variables designent le meme tableaux

Évidement ils sont maintenant égaux

t4===t3
t4==t3

et si l'on modifie une case les deux tableaux sont affectés

console.log("t3 avant ",t3)
console.log("t4 avant ",t4)
t3[2]=-1
console.log("t3 après ",t3)
console.log("t4 après ",t4)

Cette gestion de la mémoire par reference n'est pas spécifique aux tableaux.
On la retrouve avec les objets que nous allons voir très bientôt

Tableaux et chaînes de caractères

Bien qu'en javascript le type caractère n'existe pas (c'est une chaîne de longueur 1 !), on peut penser une chaîne de caractère comme un tableau de chaînes de longueur 1 (tableaux de caractères)

Mais attention même si certaine ou notation ou fonctions pour les manipuler sont les mêmes , le type string n'est pas vraiment un tableau de chaînes.

On a bien

let s="abc";
let t=["a","b","c"]
s.length===t.length
s[1]===t[1]

mais

> "abc"==="abc"
true
> ["a","b","c"]===["a","b","c"]
false

Nous approfondirons les tableaux après avoir vu le minimum sur les objets.