Nombre d'éléments dans un objet javascript


104

Existe-t-il un moyen d'obtenir (de quelque part) le nombre d'éléments dans un objet javascript ?? (c.-à-d. complexité en temps constant).

Je ne trouve pas de propriété ou de méthode permettant de récupérer ces informations. Jusqu'à présent, je ne peux penser qu'à faire une itération dans toute la collection, mais c'est du temps linéaire.
C'est étrange qu'il n'y ait pas d'accès direct à la taille de l'objet, vous ne pensez pas.

EDIT:
je parle de l' Objectobjet (pas des objets en général):

var obj = new Object ;

5
Déjà répondu ici stackoverflow.com/questions/126100/… Object.keys (obj) .length
spats

Réponses:


155

Bien que les implémentations JS puissent suivre une telle valeur en interne, il n'y a pas de moyen standard de l'obtenir.

Dans le passé, la variante Javascript de Mozilla exposait le non-standard__count__ , mais elle a été supprimée avec la version 1.8.5.

Pour les scripts inter-navigateurs, vous êtes obligé d'itérer explicitement les propriétés et de vérifier hasOwnProperty():

function countProperties(obj) {
    var count = 0;

    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
            ++count;
    }

    return count;
}

Dans le cas d'implémentations compatibles ECMAScript 5, cela peut également être écrit comme (Félicitations à Avi Flax )

function countProperties(obj) {
    return Object.keys(obj).length;
}

Gardez à l'esprit que vous manquerez également des propriétés qui ne sont pas énumérables (par exemple, un tableau length).

Si vous utilisez un framework tel que jQuery, Prototype, Mootools, $ peu importe le dernier battage publicitaire, vérifiez s'ils sont fournis avec leur propre API de collections, ce qui pourrait être une meilleure solution à votre problème que d'utiliser des objets JS natifs.


11
Putain, j'oublie toujours hasOwnProperty. Trop de temps dans le pays .NET, je vous le dis. +1
annakata

2
jQuery utilise un objet pour ses collections qu'il obtient à partir de requêtes et expose cette valeur avec une propriété length.
Nosredna

6
Firefox4 __count__est parti :(
Timo Huovinen

1
Y a-t-il un moyen de faire cela sans un for in? Je suis dans le même type de liaison mais j'aimerais lui faire passer JSLint si possible.
lampadaire

1
pourquoi avons-nous besoin hasOwnProperty()?
swisswiss

100

Pour ce faire dans n'importe quel environnement compatible ES5

Object.keys(obj).length

(Prise en charge du navigateur à partir d' ici )
(Doc sur Object.keys ici , inclut la méthode que vous pouvez ajouter aux navigateurs non ECMA5)


2
Ce n'est pas la bonne question sur laquelle poser cette réponse. Avec cela, vous prenez toutes les clés de l'objet, en les plaçant dans un tableau nouvellement créé, puis en récupérant la propriété length de ce nouveau tableau.
GetFree

13
Ce n'est peut-être pas le programme le plus efficace, mais c'est le plus efficace pour les développeurs.
superluminaire

9

si vous utilisez déjà jQuery dans votre build, procédez comme suit:

$(yourObject).length

Cela fonctionne très bien pour moi sur les objets, et j'avais déjà jQuery comme dépendance.


5
Etrange ... ça ne marche pas pour moi. Je reçois toujours 1. La réponse de ZelkiN fonctionne pour moi.
mike rodent

3
Ce code renvoie toujours 1. Juste 1 objet. Il ne compte pas les éléments
BeRocket

5
function count(){
    var c= 0;
    for(var p in this) if(this.hasOwnProperty(p))++c;
    return c;
}

var O={a: 1, b: 2, c: 3};

count.call(O);

2

AFAIK, il n'y a aucun moyen de le faire de manière fiable, sauf si vous passez à un tableau. Ce qui, honnêtement, ne semble pas étrange - il me semble assez simple que les tableaux soient dénombrables et que les objets ne le soient pas.

Probablement le plus proche que vous obtiendrez est quelque chose comme ça

// Monkey patching on purpose to make a point
Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this ) i++;
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 3

Mais cela crée des problèmes, ou du moins des questions. Toutes les propriétés créées par l'utilisateur sont comptées, y compris la fonction _length elle-même! Et bien que dans cet exemple simple, vous puissiez l'éviter en utilisant simplement une fonction normale, cela ne signifie pas que vous pouvez empêcher d'autres scripts de le faire. donc que fais-tu? Ignorer les propriétés de la fonction?

Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this )
  {
      if ( 'function' == typeof this[p] ) continue;
      i++;
  }
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 2

En fin de compte, je pense que vous devriez probablement abandonner l'idée de rendre vos objets dénombrables et trouver une autre façon de faire tout ce que vous faites.


8
DANGER WILL ROBINSON! Ne pas proto contre l' objet! Tout descend d'Object, vous paralyserez le traitement du client comme celui-ci si vous effectuez un travail JS considérable.
annakata

5
Euh ... n'avez-vous pas lu la partie où j'ai écrit dans un commentaire "Monkey patching exprès pour faire un point" - allez, je l'ai fait délibérément pour que les gens ne reviennent pas un peu à ce sujet. De plus, même si je ne préconise pas le patching de singe, vous vous méprenez sur le fonctionnement de la chaîne de prototypes en Javascript si vous pensez que cela causerait des problèmes de performances video.yahoo.com/watch/111585/1027823
Peter Bailey

Alors ... c'est à faire ou à ne pas faire?
OscarRyz

Dans "Javascript: The Good Parts", il prototypera l'objet avec une méthode "create ()". Je crois que c'est le livre définitif sur Javascript.
Chris Dutrow

1

Le concept de nombre / longueur / dimensionnalité n'a pas vraiment de sens pour un objet, et en avoir besoin suggère que vous voulez vraiment un tableau pour moi.

Edit: m'a fait remarquer que vous voulez un O (1) pour cela. Pour autant que je sache, aucun moyen n'existe, j'en ai peur.


Il a proposé de se répéter, ce qu'est cette solution. Il avait besoin d'un moyen O (1) pour y parvenir ...
Thomas Hansen

Tu as plutot raison. Devrait vraiment lire les questions de manière plus approfondie.
annakata

En fait, les objets sont ce qui se rapproche le plus d'une carte dans JS. Les cartes ont de la longueur.
Cristian Vrabie le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.