2009-06-05 15 views
73

¿Hay una manera de conseguir (de alguna parte) el número de elementos en un objeto de javascript ?? (es decir, complejidad de tiempo constante).número de elementos de un objeto de javascript

no puedo encontrar una propiedad o un método que recuperar esa información. Hasta ahora solo puedo pensar en hacer una iteración a través de toda la colección, pero ese es el tiempo lineal.
Es extraño que no haya acceso directo al tamaño del objeto, ¿no crees?

EDIT:
Estoy hablando sobre el objeto Object (no objetos en general):

var obj = new Object ; 
+3

Ya he respondido aquí http://stackoverflow.com/questions/126100/how-to-efficiently-count-the-number-of-keys-properties-of-an-object-in-javascrip Object.keys (obj) .length – spats

Respuesta

115

Aunque las implementaciones JS pueden realizar un seguimiento de un valor tal internamente, no hay forma estándar para conseguirlo.

En el pasado, la variante de Javascript de Mozilla expuestos al non-standard __count__, pero se ha eliminado con la versión 1.8.5.

Para secuencias de comandos entre el navegador que está pegado con la iteración de forma explícita sobre las propiedades y la comprobación hasOwnProperty():

function countProperties(obj) { 
    var count = 0; 

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

    return count; 
} 

En caso de ECMAScript 5 implementaciones capaces, esto también se puede escribir como (Felicitaciones a Avi Flax)

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

Tenga en cuenta que también perderá propiedades que no se pueden enumerar (por ejemplo, una matriz length).

Si está utilizando un framework como jQuery, Prototype, Mootools, $ whatever the newest-hype, verifique si vienen con su propia API de colecciones, que podría ser una mejor solución a su problema que usar JS nativo objetos.

+6

Maldita sea, siempre olvido hasOwnProperty. Demasiado tiempo en .NET land, te digo. +1 – annakata

+0

jQuery usa un objeto para sus colecciones que obtiene de las consultas, y expone ese valor con una propiedad de longitud. – Nosredna

+0

Funciona muy bien, ¡gracias por tu publicación! +1 –

1

El concepto de número/longitud/dimensionalidad no tiene mucho sentido para un objeto, y necesitarlo sugiere que realmente quieres un arreglo para mí.

Editar: me señaló que desea un O (1) para esto. Que yo sepa, no existe tal forma, me temo.

+0

se me ocurre jQuery probablemente tiene una manera de hacer esto ... – annakata

+0

Propuso iterar a sí mismo, que es esta solución. Necesitaba una forma O (1) para lograr esto ... –

+0

Tienes razón. Realmente debería leer las preguntas más a fondo. – annakata

2

yo sepa, no hay manera de hacer esto de forma fiable, a menos que cambie a una matriz. Que honestamente, no parece, me parece bastante sencillo que los arreglos sean contables y los objetos no.

Probablemente el que más se aproxima es algo como esto

// 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 

pero esto crea problemas, o al menos preguntas. ¡Todas las propiedades creadas por el usuario se cuentan, incluida la función _length! Y aunque en este simple ejemplo puede evitarlo simplemente usando una función normal, eso no significa que pueda evitar que otros scripts hagan esto. ¿Entonces, Qué haces? Ignorar las propiedades de la función?

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 

Al final, creo que probablemente debería abandonar la idea de hacer sus objetos contable y encontrar otra manera de hacer lo que sea que estás haciendo.

+8

¡PELIGRO SERÁ ROBINSON! Hacer * NO * proto contra Object! Todo desciende de Object, paralizará el procesamiento del cliente de esta manera si está haciendo una cantidad considerable de trabajo de JS. – annakata

+4

Uh ... ¿no leyó la parte donde escribí en un comentario "Parcheo de mono a propósito para hacer un punto" - vamos, lo hice deliberadamente para que la gente no volteara sobre eso. Además, aunque no defiendo el parche de monos, no entiendes cómo funciona la cadena de prototipos en Javascript si crees que esto podría causar problemas de rendimiento http://video.yahoo.com/watch/111585/1027823 –

+0

Así que ... esto es ¿un hacer o un no? – OscarRyz

6
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); 
0

Se puede utilizar:

({ foo:55, bar:99 }).__count__ // is: 2 

se ha tomado de here

+2

Esto se ve como una propiedad solo FF. – EndangeredMassa

+0

En referencia declaró su característica de JavaScript 1.8. –

+0

tenga en cuenta que esta propiedad ya no está disponible en FireFox 4 –

58

Para hacer esto en cualquier entorno compatible con ES5

Object.keys(obj).length 

(Compatibilidad con navegadores de here)
(Doc en Object.keys here, incluye el método puede agregar a los navegadores no ECMA5)

+1

Esta no es la pregunta correcta para poner esta respuesta. Con eso, está tomando todas las claves del objeto, colocándolas en una matriz recién creada y luego recuperando la propiedad de longitud de esa nueva matriz. – GetFree

+12

Pero da la cantidad correcta de elementos en el objeto ... –

+1

Esta es la respuesta correcta. – tolmark

13

si ya está utilizando jQuery en su construcción acaba de hacer esto:

$(yourObject).length 

Funciona muy bien para mí en los objetos, y ya tenía jQuery como una dependencia.

+1

Extraño ... esto no funciona para mí. Siempre obtengo 1. La respuesta de ZelkiN funciona para mí. –

Cuestiones relacionadas