Array.length donne une longueur incorrecte

Si j'ai un tableau ayant l'objet comme valeurs aux indices comme:

var a = []; a[21] = {}; a[90] = {}; a[13] = {}; alert(a.length); // outputs 91 

J'ai trouvé une solution de contournement pour obtenir la longueur réelle:

 function getLength(arr) { return Object.keys(arr).length; } var a = []; a[21] = {}; a[90] = {}; a[13] = {}; alert(getLength(a)); 

Mais, pourquoi JS donne-t-il une longueur incorrecte lorsque les objets sont stockés à des indices aléatoires? Il ajoute simplement 1 au plus grand indice trouvé sur un tableau. Comme dans l'exemple ci-dessus, 90 était le plus grand indice. Il ajoute simplement 1 et donne 91 comme sortie. Manifestation

C'est parce que la length vous donne le prochain index disponible dans le tableau.

DOCS

ArrayLength

Si le seul argument passé au constructeur Array est un nombre entier entre 0 et 2 ^ 32-1 (inclus), cela renvoie un nouveau tableau JavaScript avec une longueur définie sur ce nombre.

Spécifications ECMA

Parce que vous n'avez pas inséré d'élément dans les autres touches que 21, 90, 13, tous les index restants ne sont undefined . DEMO

Pour obtenir le nombre réel d'éléments dans le tableau:

 var a = []; a[21] = {}; a[90] = {}; a[13] = {}; var len = 0; for (var i = 0; i < a.length; i++) { if (a[i] !== undefined) { len++; } } document.write(len); 

Parce que c'est le comportement de Array.length comme décrit dans la spécification ECMAScript .

La propriété length de cet objet Array est une propriété de données dont la valeur est toujours supérieure à celle du nom de chaque propriété effaçable dont le nom est un index de tableau.

Donc, Array.length est toujours l'indice du dernier article + 1.

Le tableau en JavaScript est une simple structure basée sur zéro. Le array.length renvoie n + 1n est l'index maximum dans un tableau.

C'est exactement ce que cela fonctionne – lorsque vous affectez le 90ème élément et que la longueur de ce tableau est inférieure à 90, elle étend un tableau à 90 et définit la valeur de l'élément 90ème. Toutes les valeurs manquantes sont interprétées comme null .

Si vous essayez le code suivant:

 var a = []; a[21] = {}; a[90] = {}; a[13] = {}; console.log(JSON.stringify(a)); 

Vous obtiendrez le JSON suivant:

[Null, null, null, null, null, null, null, null, null, null, null, null, null, {}, null, null, null, null, null, null, null, {}, null, null , Null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null , Null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null , Null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, {}]

En outre, array.length n'est pas une valeur lisible.
Si vous définissez une valeur de length inférieure au courant, le tableau sera redimensionné:

  var arr = [1,2,3,4,5]; arr.length = 3; console.log(JSON.stringify(arr)); // [1,2,3] 

Si vous définissez une valeur de length supérieure à celle actuelle, le tableau sera également agrandi:

  var arr = [1,2,3]; arr.length = 5; console.log(JSON.stringify(arr)); // [1,2,3,null,null] 

Dans le cas où vous devez affecter de telles valeurs, vous pouvez utiliser des objets JS.
Vous pouvez les utiliser comme tableau associatif et attribuer n'importe quelle paire clé-valeur.

 var a = {}; a[21] = 'a'; a[90] = 'b'; a[13] = 'c'; a['stringkey'] = 'd'; a.stringparam = 'e'; // btw, a['stringkey'] and a.stringkey is the same console.log(JSON.stringify(a)); // returns {"13":"c","21":"a","90":"b","stringkey":"d","stringparam":"e"} console.log(Object.keys(a).length); // returns 5 

C'est parce que vous avez un [90] comme indice le plus important, de sorte que l'indice commence de 0 à 90 devient 91 de longueur.

Et où vous n'avez pas passé les valeurs comme [80], etc. javascript les stocke comme un trou, par exemple [1, , 3, , ,90] ,,, [1, , 3, , ,90] où les virgules sont utilisées indique le trou dans le tableau.

Si vous essayez d'accéder à ces valeurs, vous obtiendrez undefined .