Dans la première version de JavaScript, il n'y avait pas de tableaux. Ils ont été introduits plus tard comme une sous-classe de la classe "mère de tous les objets" : Object
. Vous pouvez tester cela assez facilement en faisant ceci :
var foo = [1,2,3,4];
for (var n in foo)
{//check if n is equal (value and type) to itself, coerced to a number
console.log(n === +(n) ? 'Number' : 'String');
}
Cela permettra d'enregistrer String
à chaque fois. En interne, toutes les touches numériques sont converties en chaînes de caractères. La propriété Length récupère simplement l'indice le plus élevé et lui ajoute 1. Rien de plus. Lorsque vous affichez votre tableau, l'objet est itéré, et pour chaque clé, les mêmes règles s'appliquent comme pour n'importe quel objet : d'abord l'instance est scannée, puis le(s) prototype(s)... donc si nous modifions un peu notre code :
var foo = [1,2,3,4];
foo[9] = 5;
for (var n in foo)
{
if (foo.hasOwnProperty(n))
{//check if current key is an array property
console.log(n === +(n) ? 'Number' : 'String');
}
}
Vous remarquerez que le tableau n'a que 5 propriétés propres, la propriété undefined
Les clés 4-8 sont indéfinies, car aucune valeur correspondante n'a été trouvée dans l'instance, ni dans aucun des prototypes sous-jacents. En bref : les tableaux ne sont pas vraiment des tableaux, mais des objets qui se comportent de manière similaire.
Comme Tim l'a fait remarquer, vous puede ont une instance de tableau avec une propriété non définie qui fait existent dans cet objet :
var foo = [1,2,undefined,3];
console.log(foo[2] === undefined);//true
console.log(foo[99] === undefined);//true
Mais là encore, il y a une différence :
console.log((foo.hasOwnProperty('2') && foo[2] === undefined));//true
console.log((foo.hasOwnProperty('99') && foo[99] === undefined));//false
RECAP, vos trois principales questions :
-
Les tableaux sont des objets, qui vous permettent de référencer leurs propriétés avec des instances numériques.
-
En undefined
ne sont pas là, elles sont simplement la valeur de retour par défaut lorsque JS scanne un objet et les prototypes et ne trouve pas ce que vous cherchez : "Désolé, ce que vous me demandez est indéfini dans mon livre." est ce qu'il dit.
-
Travailler avec des tableaux largement indéfinis n'affecte pas la taille de l'objet lui-même, mais accéder à une clé indéfinie peut être très difficile, très un peu plus lent, car les prototypes doivent aussi être scannés.
Mise à jour :
Juste en citant la norme Ecma :
15.4 Objets de type tableau
Les objets de type tableau accordent un traitement spécial à une certaine catégorie de noms de propriétés. Un nom de propriété P (sous la forme d'une valeur de type String) est un index de tableau si et seulement si ToString(ToUint32(P)) est égal à P et ToUint32(P) n'est pas égal à 2^32 1. Une propriété dont le nom de propriété est un indice de tableau est également appelée un élément. Chaque objet Array possède une propriété longueur dont la valeur est toujours un nombre entier non négatif inférieur à 2^32. La valeur de la propriété length est numériquement plus grande que le nom de chaque propriété dont le nom est un indice de tableau. propriété d'un objet Array est créée ou modifiée, les autres propriétés sont ajustées si nécessaire pour maintenir cet invariant. Plus précisément, chaque fois que l'on ajoute une propriété dont le nom est un indice de tableau, la propriété length est est modifiée, si nécessaire, pour être supérieure d'une unité à la valeur numérique de cet indice de tableau. est modifiée, chaque propriété dont le nom est un indice de tableau et dont la valeur n'est pas inférieure à la nouvelle longueur longueur est automatiquement supprimée. Cette contrainte s'applique uniquement aux propriétés propres d'un objet Array et n'est pas affectée par la propriété length. n'est pas affectée par les propriétés de longueur ou d'indice de tableau qui peuvent être héritées de ses prototypes.
On dit d'un objet, O, qu'il est clairsemé si l'algorithme suivant retourne vrai :
1. Soit len le résultat de l'appel de la méthode interne [[Get]] de O avec l'argument "length".
2. Pour chaque nombre entier i dans le ra
a. Soit elem le résultat de l'appel de la méthode interne [[GetOwnProperty]] de O avec l'argument [ ]
b. Si elem est indéfini, retourne true.
3. Faux retour.