web-dev-qa-db-fra.com

Nombre d'éléments dans un objet javascript

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

Je n'arrive pas à trouver une propriété ou une méthode permettant de récupérer cette information. Jusqu'ici, je ne peux penser qu'à parcourir une collection complète, mais c'est du temps linéaire.
C'est étrange, il n'y a pas d'accès direct à la taille de l'objet, vous ne pensez pas.

EDIT:
Je parle de l'objet Object (pas des objets en général):

var obj = new Object ;
95
GetFree

Bien que les implémentations de JS puissent garder une trace d'une telle valeur en interne, il n'existe pas de moyen standard pour l'obtenir.

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

Pour les scripts inter-navigateurs, vous êtes obligé de parcourir 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 suit (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, le length d'un tableau).

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

143
Christoph

Pour ce faire dans n'importe quel environnement compatible ES5

Object.keys(obj).length

(Support du navigateur de ici )
(Doc sur Object.keys here , inclut la méthode que vous pouvez ajouter aux navigateurs non-ECMA5)

86
ZelkiN

if vous utilisez déjà jQuery dans votre construction, procédez comme suit:

$(yourObject).length

Cela fonctionne bien pour moi sur les objets, et jQuery était déjà une dépendance.

11
IndelibleHeff
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);
5
kennebec

Autant que je sache, 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 , me semble assez simple: les tableaux sont dénombrables et les objets ne le sont 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 éviter cela 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 comptables et de trouver un autre moyen de faire ce que vous faites.

2
Peter Bailey

Le concept 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: Il m’a fait remarquer que vous souhaitiez un O(1) pour cela. À ma connaissance, il n’existe aucun moyen de ce genre.

1
annakata