11546 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

J'aurai besoin de vos compétences pour m'expliquer un petit truc qui me chiffonne en JS.

J'ai un tableau t dont les clés sont des chaîne de caractères représentant des entiers. Exemple :

var t = [];
t["4"] = "toto";


Si j'affiche t dans la console de firebug, j'obtiens :

[undefined, undefined, undefined, undefined, "4"]

Et la taille de mon tableau est 5 alors qu'il s'agit d'un tableau associatif (idem avec IE ou FF).

Les clés sont des chaînes de caractères, je ne comprends pas pourquoi cela fait comme si c'était des entiers.

En fait, dans mon cas, j'utilise un tableau associatif pour stocker des id (codés sur 8 caractères) et je me demande donc si le tableau réserve autant de cases que la valeur de mon plus grand id.

A votre avis, est-ce que cela diminue les performances de mon code JS, est-ce qu'il est plus gourmand ?

Merci d'avance.

Frodum
Javascript aura fait une conversion automatique String->Number.

Il serait intéressant de vérifier si t[4] et t["4"] font référence au même élément. Probablement que oui.

Maintenant je ne sais pas si le fait de déclarer t["123123"] initialise un tableau de +100000 éléments. A vérifier également.
Quoi qu'il en soit, si c'est le cas, c'est une perte de performances par rapport à un tableau associatif ne comportant que quelques éléments, surtout j'imagine pas la mémoire gaspillée. Au pire, ajoute une lettre devant ton identifiant p.ex. t["i4"]
QuentinC a écrit :
Javascript aura fait une conversion automatique String->Number.

Il serait intéressant de vérifier si t[4] et t["4"] font référence au même élément. Probablement que oui.
Je confirme.


QuentinC a écrit :

Maintenant je ne sais pas si le fait de déclarer t["123123"] initialise un tableau de +100000 éléments. A vérifier également.
Quoi qu'il en soit, si c'est le cas, c'est une perte de performances par rapport à un tableau associatif ne comportant que quelques éléments, surtout j'imagine pas la mémoire gaspillée. Au pire, ajoute une lettre devant ton identifiant p.ex. t["i4"]


C'est là tout mon interrogation et j'ai rien trouvé de concluant sur le net.
Le plus simple c'est encore d'essayer.

Déclarer un tel tableau et vérifier la variation d'occupation mémoire, par exemple à l'aide du gestionnaire des tâches sous windows (ou mieux si on a un outil spécifique et plus précis). Un tableau de 100000 éléments occupera à coup sûr au minimum 400 Ko d'espace mais ça peut facilement monter jusqu'à 3-4 Mo... ce qui n'est plus négligeable.
Bon, j'ai testé avec le gestionnaire des tâches, rien de très concluant car ce n'est pas très précis.

J'ai fouillé un peu sur le web et j'ai trouvé sur ce site http://docstore.mik.ua/orelly/webprog/jscript/ch09_01.htm :

Arrays in JavaScript may be sparse. This means that array indexes need not fall into a contiguous range of numbers; a JavaScript implementation may allocate memory only for those array elements that are actually stored in the array. Thus, when you execute the following lines of code, the JavaScript interpreter will typically allocate memory only for array indexes 0 and 10,000, not for the 9,999 indexes between:

a[0] = 1;
a[10000] = "this is element 10,000";


Ce qui me fait penser que pour les tableaux associatifs avec les clés en chaîne de caractères (représentant des nombres), il n'y a aucune raison que cela soit différent des tableaux à index.
C'est à dire qu'il n'y aura pas d'allocation mémoire pour les cases "vides" bizarrement générées (cf mon premier message dans ce sujet)


Je pense en fait que
1. le parcours d'un tableau se fait de la façon suivante : for (var i=0; i<tab.length; i++) lorsque la propriété length de l'objet tab existe.
2. tab["6"] n'est pas un tableau associatif (je ne sais pas pourquoi, ptet que l'interpréteur JS considère que tab["6"] == tab[6]) et donc possède une propriété length

Le 1. et 2. implique donc que lorsque je demande l'affichage du tableau dans firebug, ça m'affiche les cases "undefined"


Je sais pas si je suis clair, mais pour conclure, j'ai l'impression qu'il n'y a pas d'allocation mémoire pour les cases vides dans mon exemple. Mais que je n'en aurai la certitude que lorsque j'aurai trouvé un moyen de le tester précisément.
Modifié par frodum (28 Jan 2009 - 17:41)
Dans un tableau, une chaine de caractère n'est pas un index ou une clef mais une propriété de l'objet. Hors le nom d'une propriété ne peut commencer par un chiffre.

t['toto'] et t.toto sont des écritures équivalentes.
Bonjour,
des tableaux avec des clés non numériques sont en fait des objets en Javascript, c'est la syntaxe JSON (http://json.org/). Ce n'est pas pareil qu'en PHP (ou tous les autres languages non prototypés comme JS)
Modifié par fabien.menager (03 Feb 2009 - 09:26)
Effectivement, il faut recourir à un objet pour définir un tableau associatif en javascript.
// définir un nouvel objet
	var t={};
// pour pouvoir écrire...
	t["4"]="toto";
// ou bien encore ...
	var id="123123";
	t[id ]="lulu";
// pour obtenir le [i]"tableau associatif"[/i] recherché
	var c="";for (i in t) c+=i+"=>"+t[i ]+"\n";
   alert(c);

Il conviendra cependant d'éviter ici (avec des chaînes non alphanumériques) les écritures t.4 ou t.123123.

Finalement la solution ne tient qu'à la première ligne !

NB : Des espaces ont été introduits après t[id ou t[i pour éviter des interprétations parasites des codes correspondants.
Modifié par Julien de Prabere (03 Feb 2009 - 09:30)
Merci pour vos réponses.

Je vais effectivement passer par les objets pour faire mes tableaux associatifs, ça m'évitera de douter.

Merci encore

Frodum