Vous êtes ici : Accueil des cours Misfu > Informatique > Apprendre la programmation > Cours Javascript > Objets comme tableaux associatifs

Traduction de la page Objects as associative arrays rédigée par Peter-Paul Koch et traduite par Christophe Bruggeman

Objets comme tableaux associatifs

Sur cette page j'explique pourquoi les objets en Javascript sont également des tableaux associatifs (associative arrays). En utilisant ces derniers vous pouvez associer un attribut key (définie en string) avec une valeur (définie en string), ce qui peut parfois être très utile.

Supposez que vous avez combiné un script mouseover / click (lien mort) Vous voulez garder des traces sur le statut de chaque image, si c’est normal, mouseovered ou clicked. En outre vous voulez pouvoir être capable d’atteindre ce statut par un nom d'image. Donc si vous avez appelée une image 'Home' vous voulez lire

theStatus['Home']

et obtenir une des valeurs 'normal', 'mouseover' ou 'clicked', correspondant à l'état actuel de l'image.
Pour faire ceci vous avez besoin des objets Javascript.

Objets dans le Javascript

Le Javascript est un langage orienté objet. Cependant, dans la pratique les objets définis par le programmeur lui-même sont rarement employés, excepté dans de complexe API DOM. Naturellement les objets standard tels que window et document ainsi que leur nombreuses progénitures sont très important, mais ils sont définis par le navigateur, pas par le programmeur.

J’ai moi-même écrit du JavaScript pendant plus de trois ans sans jamais définir un objet. La technique expliquée sur cette page est la première utilisation pratique d’une programmation orientée objets que j'ai trouvés.

Puisque les seuls autres langages de programmation que je connaisse sont le commodore 64 Basic (qui n'est pas orienté objet) et Perl (qui n'a pas besoin d'être objet orienté) et puisque je n'ai aucune formation formelle dans la programmation, je ne peut pas écrire une introduction générale sur l’objet et la programmation orientée objet. Par conséquent une rapide vue d'ensemble devrait suffire.

Méthodes et propriétés

Dans le Javascript vous pouvez définir vos propres objets. En outre, vous pouvez assigner des méthodes et des propriétés à chaque objet, pré écrite ou prédéfinie.

Les fonctions basiques en JavaScript sont également des méthodes (d’ou les parenthèses). Si vous faites

document.write('text')

vous exécutez la méthode prédéfini write() du document objet. Si vous écrivez vos propres fonctions vous ajoutez des méthodes à l’objet window, le parent de tous autres objets Javascript.

De même, si vous demandez le innerHeight d'une page, vous accédez à une propriété de l’objet window et si vous définissez une variable par vous même vous ajoutez vraiment une nouvelle propriété à l’objet window.

Ainsi vous employez déjà des méthodes et des propriétés dans votre JavaScripting journalier. Puisque la plupart de ces dernières sont des fonctions et des variables préprogrammées, vous n’avez habituellement aucune raison de vous inquiéter des objets eux-mêmes, ils sont justes des sortes de 'boîtes noires’ qui contiennent la substance utile. Les méthodes et les propriétés (fonctions et variables) que vous définissez vous-même sont généralement ajoutés à l’objet window.

Définir un objet et des propriétés

Maintenant nous voulons créer un objet par nous même. C'est simple :

var theStatus = new Object;

Maintenant que nous avons initialisé notre objet theStatus nous pouvons commencer à ajouter des propriétés (dans cet exemple nous n'avons pas besoin de méthodes). Ce que nous voulons doit créer une propriété pour chaque image de la page. Nous pourrions faire

theStatus.Home = 'normal';

Maintenant nous avons ajouté une nouvelle propriété Home à notre objet et placez sa valeur dans le string 'normal'. (Rappelez-vous que le Javascript est sensible à la case, ainsi la propriété home n'existe pas, seulement Home.)

Tout ceci est très utile, mais en utilisant cette notation nous rencontrerons des problèmes plus tard. Supposez qu’on crée une propriété de theStatus pour chaque image de la page. La propriété devrait avoir le même nom que l'image et sa valeur devrait être 'normal'.

Nous ne pouvons pas faire :

var x = document.images;
for (var i=0;i<x.length;i++)
{
	var theName = x[i].name;
	theStatus.theName = 'normal';
}

Nous passons entièrement le tableau d’images de la page, nous prenons le nom de chaque image et puis nous essayons de créer une nouvelle propriété avec le même nom. Mais le code ci-dessus ne fonctionne pas. Chaque fois que vous faites

	theStatus.theName = 'normal';

Le Javascript crée fidèlement une nouvelle propriété appelée theName et met sa valeur à 'normal'. Après exécution de ce script vous avez seulement une propriété theName. Ce n'est pas ce qui nous voulons, nous voulons une propriété pour chaque image.

Associative arrays (tableaux associatifs)

Donc nous devons employer un des mystères du Javascript. Dans le Javascript, les objets sont également des associative arrays (ou hashes). C'est-à-dire, que la propriété

theStatus.Home

peut aussi être lu ou écrite en appelant

theStatus['Home']

Ainsi, vous pouvez accéder à chaque propriété en écrivant le nom de la propriété comme une chaîne (string) dans ce tableau. Un tel tableau associe à chaque attribut key une valeur (dans ce cas-ci le key Home est associée avec la valeur normal). Dans le langage de programmation Perl on appel ça également un hash.

À la différence du Perl, qui exige de vous de créer explicitement un tel tableau associatif, le Javascript crée automatiquement un tableau associatif pour chaque objet.

Vous voyez ce comportement avec des objets communs comme un formulaire. Vous pouvez accéder à un formulaire en exécutant l'un ou l'autre de ces appels DOM :

document.forms['theForm']
document.forms.theForm

(vous pouvez également employer document.theForm mais c'est un cas spécial, un comportement inhabituel des tableaux Javascript objects/associative).

Ainsi quand nous voulons placer le statut de chaque image à 'normal' dans notre objet, nous faisons

var x = document.images;
for (var i=0;i<x.length;i++)
{
  var theName = x[i].name;
  theStatus[theName] = 'normal';
}

et cela fonctionne. Maintenant theName (un string) est mis entre crochets [] là où un string est attendu. Ainsi vous créez une nouvelle paire de key/value, qui est identique à une nouvelle propriété avec une valeur.

Tout ça c’est la magie du JavaScript. Je ne comprends pas toujours ce que je fais, mais cela fonctionne bien. Maintenant vous avez le pouvoir de laisser un nom ou string se rapporter à un autre.

for (var i in objet)

for (var i in objet) est équivalent à foreach $key (keys %hash) en Perl.

De la même manière que vous pouvez passer par chaque élément d'un tableau normale par

var x = [the array];
for (var i = 0;i<x.length;i++)
{
  do something with x[i]
}

vous pouvez également passer par chaque élément d'un tableau associatif (associative array). Supposez que vous vouliez passer pour toutes les images par la valeur du statut. Si le statut de l'image est 'mouseover' vous voulez appeler une fonction callFn() et lui passer le nom de l'image. Vous pouvez naturellement mais péniblement écrire tout ça :

if (theStatus.Home == 'mouseover')
   callFn('Home'):
if (theStatus.Place == 'mouseover')
   callFn('Place'):
etc...

ou

if (theStatus['Home'] == 'mouseover')
   callFn('Home'):
if (theStatus['Place'] == 'mouseover')
   callFn('Place'):
etc...

Mais ceci mène rapidement à d'immenses scripts. En outre, si vous renommer une image plus tard vous devez également changer une ligne de code et bien sûr vous oubliez, donc vous obtenez des erreurs etc...

Heureusement le JavaScript a la déclaration for/in qui est la exactement pour cette situation. Si vous faites

for (var i in theStatus)
{
  if (theStatus[i] == 'mouseover')
    callFn(i)
}

vous passez par toutes les propriétés de l’objet theStatus (= tous les keys dans le tableau associatif theStatus). La variable i devient successivement le nom de chaque propriété de l'objet (key des tableaux associatifs) ainsi si vous faites quelque chose avec theStatus[i] ça ce répercutera sur chaque propriété.
Dans ce cas-ci, si le statut d'une image a la valeur 'mouseover' vous appelez callFn() et lui passez le key (le nom de l'image).

(Notez que le JavaScript ne garantit pas un ordre particulier pour les propriétés. Donc vous ne devez pas vous attendre à voir apparaître en premier la propriété qui a été définie la première, il ce peut qu’elle ne vienne qu’à la fin.)

Testez le script

Un script minuscule pour le plaisir d’essayer. Si vous cliquez sur ce lien ce script sera exécuté :

var theStatus = new Object();

function testIt()
{
	theStatus.Home = 'mouseover';
	theStatus['Place'] = 'click';
	for (var i in theStatus)
	{
		alert('theStatus[\''+i+'\'] is ' + theStatus[i])
	}
}

Cours JavaScript : Introduction Javascript Ajouter du Javascript Détection d'objet Déclarations Fontions String DOM Booléen DOM intermédiaire Objets This MouseOver Imprimer Détection navigateur