Les langages du web > Le Javascript

JavaScript pour Pro

Complément au mini-cours sur JavaScript

Table des matières - Plan

Avant de lire ce cours, je choisis mes couleurs

Le mini-cours présentait des notions de bases (utilisées avant 2015). Ce cours le complète par des notions plus pointues.

En 2015, JavaScript a fortement évolué. La version 6 (ou version 2015) est l'aboutissement de 15 ans de travail. C'est donc plus qu'une version majeure, c'est une refonte, une nouvelle façon de coder. Des nouveautés sont donc apparues. Des nouveaux mots clé : let, set, map, class ... et de nouvelles méthodes, ainsi que la notion de "module".

Liste des 10 principales nouveautés
  1. let and const Keywords
  2. Arrow Functions
  3. Multi-line Strings
  4. Default Parameters
  5. Template Literals
  6. Destructuring Assignment
  7. Enhanced Object Literals
  8. Promises
  9. Classes
  10. Les modules

Historique des versions

Pré-requis

La console

La console s'affiche en tapant, lorsque le navigateur est actif : MAJ + CTRL + I, puis sur l'onglet "Console".

console.log(obj1 [, obj2, ..., objN]);

Erreurs inexplicables ?

L'analyse du code HTML et de celui du code JS ne révèle aucune erreur. Et, pourtant cela ne se passe pas comme prévu. La console est alors très précieuse. Exemple :

Code HTML :

  <!--<p>
        <input type="color" id="bodyBackgroundColor" />
        = Couleur de fond de la zone <i>body</i>.
      </p>
  -->
      <p>
        <input type="color" id="containerBackgroundColor"  />
        = <b>couleur de fond</b> de la zone qui contient <i>div id="container"</i>.
      </p>

Mauvais code JS :

  document.getElementById("bodyBackgroundColor").value = bodyBackgroundColor;
  document.getElementById("containerBackgroundColor").value = containerBackgroundColor;

Plus rien ne fonctionne. Pourquoi ?

Affichage dans la console :

Uncaught TypeError: Cannot set property 'value' of null
/* suivi du numéro de la ligne de code ayant provoqué cette erreur */

Traduction : Il n'est pas possible de mettre à jour la propriété value de l'objet null.

Explication :

L'accès à la balise identifiée par bodyBackgroundColor n'est plus possible, puisque cette balise a été mise dans un commentaire. Or, le JS s'arrête sur la première erreur rencontrée. Le code qui suit cette instruction n'est plus exécuté !

La solution : Ne pas oublier de commenter également le code JS faisant appel à cette balise HTML devenue inaccessible.

Bon code JS :

  /*document.getElementById("bodyBackgroundColor").value = bodyBackgroundColor; */
  document.getElementById("containerBackgroundColor").value = containerBackgroundColor;

Les variables

var

Source

La portée d'une variable déclarée avec var est le contexte d'exécution courant, c'est-à-dire : la fonction qui contient la déclaration ou le contexte global si la variable est déclarée en dehors de toute fonction.

Les variables non-déclarées sont toujours globales.

S'il n'y a aucune valeur fournie, la variable vaudra undefined.

Il est fortement recommandé de toujours déclarer les variables, qu'elles soient dans une fonction ou dans la portée globale.

Déclarer une variable n'importe où dans le code équivaut à la déclarer au début de son contexte d'exécution. Toutefois, pour une meilleure lisibilité du code, il est préférable de les déclarer au début du contexte, comme en C.

const

Source

La valeur d'une constante ne peut pas être modifiée par des réaffectations ultérieures.

Par convention, les constantes sont en majuscules.

let

Source, existe depuis ECMAScript 2015

L'instruction let permet de déclarer une variable dont la portée est celle du bloc courant (= encadré par {}), éventuellement en initialisant sa valeur.

Les blocs courants sont des structures (répétitives ou conditionnelles, telles que for, while,... ou if, switch) ou des fonctions. La portée de cette variable s'étend aux sous-blocs.

typeof()

Le type de la variable est retourné par la fonction typeof().

Cette fonction retourne la string = number, string, undefined, boolean ou object

La valeur (et non le type) d'une variable peut aussi être null.

function typeDe(){
  /* type = number, string, undefined, boolean, object (proto: Array, Object) */
  console.log("function typeDe()");

  var number1 = 5; /* Nombre entier (notation décimale) */
  console.log(number1, "type = "+typeof(number1)); /* Affiche : 5 "type = number" */

  var number2 = 5.5+2; /* Nombre réel (notation décimale) */
  console.log(number2, "type = "+typeof(number2)); /* Affiche : 7.5 "type = number" */

  var concatenation = '5,5'+2; /* conversion de type */
  console.log(concatenation, "type = "+typeof(concatenation));
  /* Affiche : 5,52 type = string */

  var number3 = 3.65e+5; /* Nombre avec exposant (notation scientifique) */
  console.log(number3, "type = "+typeof(number3)); /* Affiche : 365000 "type = number" */

  var number4 = 0x16; /* Nombre entier (notation hexadécimale) */
  console.log(number4, "type = "+typeof(number4)); /* Affiche : 22 "type = number" */

  var number5 = 0o10; /* Nombre entier (notation octale) */
  console.log(number5, "type = "+typeof(number5)); /* Affiche : 8 "type = number" */

  var text1 = "Mon premier texte"; /* Avec des guillemets */
  console.log(text1, "type = "+typeof(text1));
  /* Affiche : Mon premier texte type = string */

  var text2 = 'Mon deuxième texte'; /* Avec des apostrophes */
  console.log(text2, "type = "+typeof(text2));
  /* Affiche : Mon deuxième texte type = string */

  var text3;
  console.log(text3, "type = "+typeof(text3)); /* Affiche : undefined "type = undefined" */

  var faux=false;
  console.log(faux, "type = "+typeof(faux)); /* Affiche : false "type = boolean" */

  var tab=[1,2];
  console.log(tab, "type = "+typeof(tab));
  /* Affiche : (2) [1, 2]0: 11: 2length: 2__proto__: Array(0) "type = object" */

  var objet={a:1,b:2};
  console.log(objet, "type = "+typeof(objet));
  /* Affiche : {a: 1, b: 2}a: 1b: 2__proto__: Object "type = object" */
}

À partir d'ECMAScript 2015, la syntaxe standard utilise un zéro suivi de la lettre « o » (en minuscule ou en majuscule) (0o or 0O). Source

Affectation d'une variable

En JavaScript, outre le type de variable, la variable est "simple" ou "objet".

La variable de type undefined n'est ni simple, ni objet. C'est une variable dont la valeur n'a pas encore été assignée ou dont la valeur correspond à la valeur non-retournée ou à la valeur retournée de type undefined.

Les variables "considérées" comme simples sont celles qui sont de type : number, boolean et string (bien que la string soit un objet); et sur lesquelles on peut faire des opérations simples (affectation ou opérations arithmétiques ou concaténation)

function affectation(){

  var number1, number2;
  number1=2;
  number2=number1;
  console.log(number2); /* Affiche : 2 */
  number1=number2=3;
  console.log(number1); /* Affiche : 3 */

  var boolean1, boolean2;
  boolean1=true;
  boolean2=boolean1;
  console.log(boolean2); /* Affiche : true */
  boolean1=boolean2=false;
  console.log(boolean1); /* Affiche : false */

  var inconnu;

  var string1, string2;
  string1="tintin";
  string2=string1;
  console.log(string2); /* Affiche : tintin */
  string1=string2="milou";
  console.log(string1); /* Affiche : milou */
  string1=inconnu;
  console.log(string1, string2); /* Affiche : undefined milou */

  var tab1, tab2;
  tab1=[1,2];        /* objet tableau */
  tab2=tab1;
  console.log(tab2); /* Affiche : array : 1,2 */
  tab1=tab2=[3,4];
  console.log(tab1); /* Affiche : array : 3,4 */
  tab1=inconnu;
  console.log(tab1, tab2); /* Affiche : undefined array : 3,4 */

  var objet1, objet2;
  objet1 = {a: 1, b: 2};  /* objet littéral */
  objet2=objet1;
  console.log(objet2);    /* Affiche : object (1,2) */
  objet1=objet2={a: 3, b: 4};
  console.log(objet1);    /* Affiche : object (3,4) */
  objet1=inconnu;
  console.log(objet1, objet2); /* Affiche : undefined object (3,4) */

  var balise1,balise2;
  balise1=document.getElementById("affectation");
  if(balise1!=null){balise2=balise1;}
  console.log(balise2);    /* Affiche : object (HTMLHeadingElement) */
  balise1=balise2=document.getElementById("btn_affectation");
  console.log(balise1);    /* Affiche : object (HTMLParagraphElement) */
  balise1=inconnu;
  console.log(balise1, balise2); /* Affiche : undefined object (HTMLParagraphElement) */
}

''   ""   ``

Avant d'être affectée à une variable (ou à une propriété, par exemple innerHTML), une string (...) doit être encadrée par : '...', "..." ou, depuis la spécification ECMAScript 2015, par `...`.

Le guillemet (aussi appelé guillemet double) a le code ASCII : 34
L'apostrophe (aussi appelé guillemet simple) a le code ASCII : 39
L'accent grave (aussi appelé backtick) a le code ASCII : 96

Seul le backtick est utilisable pour former une chaîne de caractères de gabarit qui permet l'interpolation de variables et d'expressions, en utilisant la syntaxe `${expression}`. Par exemple, la chaîne de caractères de gabarit : ``Bonjour, ${nom}`` affichera "Bonjour" suivi de la valeur de la variable `nom`.

Un littéral de gabarits conserve les retours à la ligne et les décalages, comme la balise pre en HTML.

Une string de gabarit qui ne contient pas d'expression peut être utilisée lorsqu'elle contient à la fois des ' et des ".

Par exemple pour inclure du code HTML :

document.getElementById("boutons").innerHTML =
`
<p>
  <button onclick="delCalculs()" type="button">Effacer le résultat de l'analyse</button>
</p>
`

Écrire qu'un bouton est type="button" n'est pas une aberration. Par défaut, il est de type="submit" (car, par défaut, un bouton est destiné à valider un formulaire)

Plus d'info sur les strings : MDN

Plus d'info sur les littéraux de gabarits : MDN

Les conditions

Un nombre qui vaut zéro, une chaîne de caractères vide, undefined ou NaN vaut false.

function trueFalse(){
  console.log("trueFalse()");
  var a, b=0, c='', d=2, e="e", f=parseInt("toto");
  if(a)console.log(a); /* n'affiche rien : a vaut undefined */
  if(b)console.log(b); /* n'affiche rien : b vaut 0 */
  if(c)console.log(c); /* n'affiche rien : c vaut est une string vide */
  if(d)console.log(d); /* Affiche : 2 */
  if(e)console.log(e); /* Affiche : e */
  if(f)console.log(f); /* n'affiche rien : f vaut NaN */
}

=== et !==

Maintenant que nous savons que une variable n'a pas seulement une valeur, mais aussi un type, ajoutons deux opérateurs de comparaison :

=== : contenu et type égal à
!== : contenu ou type différent de

function compareAussiType(){
  console.log("compareAussiType()");
  var number=4, text='4', booleen=false, text2='false', number2=0;
  console.log(number == text); /* Affiche « true » */
  console.log(number === text); /* Affiche « false » */
  console.log(number2 == booleen); /* Affiche « true » */
  console.log(number2 === booleen); /* Affiche « false » */
  console.log(booleen == text2); /* Affiche « false » */
  console.log(booleen === text2); /* Affiche « false » */
}

else if

La structure if...else permet de résoudre tous les cas. Le débutant ne doit pas en connaître d'autres.

Si le but de cette structure vise à modifier une variable, la clause else n'est pas nécessaire ! Il suffit de l'affecter avant cette structure et de la ré-affecter si le test est vrai.

  var floor = parseInt(prompt("Entrez l'étage où l'ascenseur doit se rendre (de -2 à 30) :"));
  if (floor == 0) {
    alert('Vous vous trouvez déjà au rez-de-chaussée.');
  } else if (-2 <= floor && floor <= 30) {
    alert("Direction l'étage n°" + floor + ' !');
  } else {
    alert("L'étage spécifié n'existe pas.");
  }

Cette structure "sinon si" n'est quasi jamais utilisée, car elle peut être remplacée par un if...else imbriqué (plus lisible)

En effet, elle équivaut à :

var floor = parseInt(prompt("Entrez l'étage où l'ascenseur doit se rendre (de -2 à 30) :"));
  if (floor == 0) {
    alert('Vous vous trouvez déjà au rez-de-chaussée.');
  } else {
    if (-2 <= floor && floor <= 30) {
    alert("Direction l'étage n°" + floor + ' !');
    } else {
    alert("L'étage spécifié n'existe pas.");
    }
  }

Ici, le if...else est imbriqué.

if...else imbriqués

Ici, le if...else est dans le else d'un if...else (parent)

Le if...else peut aussi être dans le if d'un if...else (parent)

La clause else est toujours facultative.

if...if = AND

function if_if(){
  var a = parseInt(prompt("a (si a=2) :"));
  var b = parseInt(prompt("b (si b=3) :"));
  /* Affichage de ce qui a été tapé */
  alert('Affichage 3 : a = '+a+'; b = '+b);
  /* test */
  if (a == 2) {
    if (b == 3) {
    alert('Affichage 1 : a=2 ET b=3 !');
    }
  }
  /* code plus court et plus lisible */
  if (a == 2 && b == 3) {
    alert('Affichage 2 : a=2 ET b=3 !');
  }
}

if...else...if = OR

function if_else_if(){
  var a = parseInt(prompt("a (si a=2) :"));
  var b = parseInt(prompt("b (si b=3) :"));
  /* Affichage de ce qui a été tapé */
  alert('Affichage 3 : a = '+a+'; b = '+b);
  /* test */
  if (a == 2) {
    alert('Affichage 1 : a=2 OU b=3 !');
  }else{
    if (b == 3) {
      alert('Affichage 1 : a=2 OU b=3 !');
    }
  }
  /* code plus court et plus lisible */
  if (a == 2 || b == 3) {
    alert('Affichage 2 : a=2 OU b=3 !');
  }
}

XOR

L'opérateur XOR n'existe pas (en Javacript 2015). Toutefois, cela peut facilement être simulé.

function myXOR(a,b){
  return ( a || b ) && !( a && b ); /* retourne true ou false */
}

function xor(){
  var a = parseInt(prompt("a (si a=2) :"));
  var b = parseInt(prompt("b (si b=3) :"));
  /* Affichage de ce qui a été tapé */
  alert('Affichage : a = '+a+'; b = '+b);
  /* test */
  if( myXOR(a,b) ){
    alert('true XOR false => true\nfalse XOR true => true');
  }else{
    alert('true XOR true => false\nfalse XOR false => false');
  }
}

switch

Lorsque les tests concernent la même variable, il est plus élégant d'utiliser la structure switch.

function switchExemple(){
  var myEntier = parseInt(prompt('Choisissez le tiroir à ouvrir (1 à 4) :'));

  switch (myEntier) {
    case 1:
        alert('Contient divers outils pour dessiner : du papier, des crayons, etc.');
    break;

    case 2:
        alert('Contient du matériel informatique : des câbles, des composants, etc.');
    break;

    case 3:
        alert('Ah ? Ce tiroir est fermé à clé ! Dommage !');
    break;

    case 4:
        alert('Contient des vêtements : des chemises, des pantalons, etc.');
    break;

    default:
        alert("Info du jour : le meuble ne contient que 4 tiroirs.");
  }
}

switch teste avec l'opérateur ===.

function switchExemple2(){

  var mystring = prompt('Entrez la valeur 1 :'); /* prompt() retourne une string */
  switch (mystring) {
    case 1:
        alert('Bravo !');
    break;

    default:
        alert('Perdu !');
  }
}

Ce code n'affichera jamais « Bravo ! »

La valeur qui suit le case peut être une string.

function switchExemple3(){

  var mystring = prompt('Entrez la valeur 1 :'); /* prompt() retourne une string */
  switch (mystring) {
    case "1":   /* ou '1' */
        alert('Bravo !');
    break;

    default:
        alert('Perdu !');
  }
}

Opérateur ternaire

http://www.yvoz.net/2010/07/csharp-operateur-ternaire-conditionnel/

L'opérateur ternaire utilise, comme son nom l'indique, trois opérandes.

rep = expr ? a : b;expr est une expression qui retourne un booléen. Si c'est true est retourné la valeur de a. Sinon, est retourné la valeur de b.

function ternaire(){
 alert('Votre catégorie : ' + (confirm('Êtes-vous majeur ?') ? '18+' : '-18'));
}

Un ternaire est un if...else qui retourne une valeur.

||

L'opérateur OU va retourner la valeur de la première variable dont le contenu est évalué à true.

function OR_particularite(){
  var a=0, b=3;
  alert(a||b); /* Affiche 3 */
}

Les boucles

Les boucles, comme les conditions, peuvent être imbriquées.

pré/post incrémentation

La post-incrémentation, incrémente la valeur après l'avoir retourné.
La pré-incrémentation, incrémente la valeur avant de la retourner.
S'il n'y pas de retour, le type d'incrémentation est sans importance.

function prePostIncrementation(){
  console.log("prePostIncrementation");
  var a=b=9;
  console.log(++a); /* Affiche : 10 */
  console.log(b++); /* Affiche : 9 */
}

break et continue

Le mot-clé break permet de sortir immédiatement d'une boucle (ou d'un switch).
Le mot-clé continue permet de reboucler immédiatement.

do while

La boucle do while ressemble très fortement à la boucle while, sauf qu'ici la boucle est toujours exécutée au moins une fois

do {
    instruction_1;
    instruction_2;
    instruction_3;
} while (condition);

for

Contrairement aux autres langages, en JavaScript, les variables déclarées - avec ou sans le mot clé var - dans le bloc d'initialisation existent encore après la boucle.

Toutefois, depuis JavaScript 2015, les variables déclarées par le mot clé let seront "détruites" à la sortie de la boucle. L'appel de variables qui n'existent plus provoque alors une erreur.

for in

Ce type de boucle sera abordé lorsque seront abordés les objets littéraux.

Les fonctions

Toute variable déclarée dans une fonction est locale; c-à-d inconnue à l'extérieure de la fonction.

À l'inverse, celle déclarée en-dehors d'une fonction est globale car elles sont accessibles partout dans le code, y compris à l'intérieur de fonctions.

Évitez le recours à des variables.

La variable locale prend le dessus sur la variable globale de même nom.

Une fonction peut être déclarée dans une fonction. Dans ce cas, elle ne pourra être appelée que par la fonction qui héberge sa déclaration.

Paramètre facultatif

On parle d'argument dans la déclaration de la fonction; et de paramètre lors de l'appel de cette fonction.

Le paramètre est comme une variable locale.

Tous les paramètres ne sont pas obligatoires. Les paramètres facultatifs sont placés après les paramètres obligatoires.

function multiplication(obligatoire, facultatif){
  if(typeof(facultatif)==="undefined")
    {facultatif = 2;
  }
  /* result = obligatoire * facultatif;
}

Les fonctions anonymes

Les fonctions, les conditions, les boucles, ... sont des structures, tandis que tout le reste (assignation de variable, exécution de fonction, ...) sont des instructions. Les instructions se terminent par un point virgule; les structures, par une accolade fermante.

La boucle do...while est une structure qui se termine par un point virgule (car elle ne se termine pas par une accolade fermante)

Exemple de création et appel d'une fonction anonyme :

  /* Une instruction assignant une structure à une variable */
  var sayHello = function() {
    alert('Bonjour !');
  };

  /* Appel de la fonction anonyme (via une variable)
  Le nom de variable est celui de la fonction ... */
  sayHello();

La variable sayHello contient une référence à une fonction. (En C, on parlerait de pointeur)

IIFE

Immediately-Invoked Function Expression

Une fonction anonyme peut être immédiatement exécutée de cette façon :

(function() {
    // Code ...
})();

Une fonction nommée peut être immédiatement exécutée de cette façon :

(function myFunction() {
    // Code ...
})();

Mais, puisqu'elle est immédiatement exécutée, la nommer ne sert à rien ...

Retourner un ensemble de valeur

Une fonction peut retourner un ensemble de valeurs sous la forme d'un objet littéral.

function retournerUnObjetLitteral(){
  var myObject = {}; /* objet vide */

  var personne = {
    prenom: 'Thibaut',
    age: 10
  };

  alert(personne.prenom); /* Affiche : Thibaut */
  alert(personne['age']); /* Affiche : 10 */

  personne.nom="PIGNÉ"; /* Ajoute une valeur */
  personne['sexe']="H"; /* Ajoute une valeur */

  return personne; /* retourne un objet (ayant plusieurs valeurs) */
}
<button onclick="alert((retournerUnObjetLitteral()).nom);">Renvoyer un objet</button>

Le bouton appelle la fonction alert() qui appelle la fonction retournerUnObjetLitteral() qui affiche deux valeurs et qui retourne un objet dont il est demandé d'afficher la propriété nom.

Une fonction peut retourner un ensemble de valeurs sous la forme d'un tableau.

function retournerUnTableau(){
  var tableau = ['Bernard',65];
  return tableau;
}

Code dans le bouton :

<button onclick="alert((retournerUnTableau())[1]);">Renvoyer un tableau</button>


Ceci clôture les informations complémentaires relatives aux 4 caractéristiques d'un langage : les variables, les conditions, les boucles et les fonctions.

Les objets

Le JavaScript n'est pas un langage typé, car les variables contiennent toujours un objet. Mais, cet objet peut être de nature différente : un nombre, un booléen, ...

Les classes contiennent trois choses distinctes :

Les méthodes se distingue des fonctions par le point qui précède leur nom. Exemple : myFunction() mais .myMethod(). De plus, une méthode s'applique toujours à un objet => myObject.myMethod().

Quelques classes courantes :

var myString = 'Test';
alert(myString.length); // Affiche : « 4 »

Les tableaux

Une chaîne de caractères (string) est un tableau de caractères.

.length

Cette propriété retourne la taille de l'objet. Si cet objet est une string, elle retournera le nombre de lettres. Si cet objet est un tableau, elle retournera le nombre de cellules.

.push()

La méthode .push() ajoute un ou plusieurs éléments (séparés par une virgule) à la fin de la liste.

.pop()

La méthode .pop() supprime le dernier élément de la liste.

.unshift()

La méthode .unshift() ajoute un ou plusieurs éléments (séparés par une virgule) au début de la liste.

.shift()

La méthode .shift() supprime le premier élément de la liste.

.reverse()

La méthode .reverse() permet d'inverser l'ordre des éléments d'un tableau : le premier élément devient le dernier et le dernier devient le premier.

Parcourir un tableau

for (var i = 0, taille = myArray.length; i < taille; i++) {
  console.log(myArray[i]);
}

String

Les propriétés et méthodes les plus courantes - .length, .charAt(), .indexOf(), .lastIndexOf(), .replace(), .substr() - ont été abordées dans le mini-cours de JavaScript sur la String

.split()

La méthode .split() attend un paramètre, qui représente la chaîne (souvent un seul caractères) qui sépare les autres chaînes. Chaque sous-chaîne trouvée est alors automatiquement placée dans la cellule d'un tableau.

myTab = myString.split(' ');

Ici, le caractère séparateur est un espace

.join()

La méthode .join() fait l'inverse de .split()

myString = myTab.join(';');

Ici, le caractère séparateur est un point-virgule.

Si vous ne spécifiez rien comme séparateur, les chaînes de caractères seront collées les unes aux autres.

.toString()

.toUpperCase()

.toLowerCase()

Les objets littéraux

Il est possible d'accéder à une valeur via un identifiant.

function retournerUnObjetLitteral(){
  var myObject = {}; /* objet vide */

  var personne = {
    prenom: 'Thibaut',
    age: 10
  };

  alert(personne.prenom); /* Affiche : Thibaut */
  alert(personne['age']); /* Affiche : 10 */

  personne.nom="PIGNÉ"; /* Ajoute une valeur */
  personne['sexe']="H"; /* Ajoute une valeur */

  return personne; /* retourne un objet (ayant plusieurs valeurs) */
}

Dans un tableau, l'ensemble des valeurs est encadré par des crochets [].
Dans un objet, cet ensemble est encadré par des accolades {}.

Dans un tableau, les valeurs sont séparées par une virgule.
Dans un objet, les couples identifiant-valeur sont également séparés par une virgule.

L'identifiant et la valeur sont séparés par deux points :

for ... in

Il n'est pas possible de parcourir un objet littéral avec une boucle for car celle-ci ne sait incrémenter qu'une variable numérique.

Pour parcourir un objet littéral, il faut utiliser la boucle for ... in (équivalent à la bouche foreach, en PHP)

function useForIn(){

  var objet={
    prenom: 'Thibaut',
    age: 10
  };

  for (var propriete in objet) { /* « propriete » = un identifiant de l'objet */
    alert(objet[propriete]);
  }

}

La boucle for ... in ne devrait être utilisée que pour parcourir un objet littéral, car elle est lente..
Pour parcourir un tableau, mieux vaut utiliser la boucle for.