2010-07-01 23 views
9

Tengo un objeto Javascript que intento usar como "hashmap". Las claves siempre son cadenas, así que no creo que necesite algo tan sofisticado como el descrito en this SO question. (Tampoco espero que el número de claves supere aproximadamente 10, por lo que no me preocupan especialmente las búsquedas que son O (n) vs. O (log n) etc.)Determinar cuántos campos tiene un objeto Javascript

La única funcionalidad que quiero que los objetos Javascript incorporados no parecen tener, es una forma rápida de calcular el número de pares clave/valor en el objeto, como lo que devuelve el Map.size de Java. Por supuesto, puede hacer algo como:

function getObjectSize(myObject) { 
    var count=0 
    for (var key in myObject) 
    count++ 
    return count 
} 

pero eso parece un poco hacky y rotunda. ¿Hay una "forma correcta" de obtener el número de campos en el objeto?

+0

La única sugerencia a su método sería añadir un parámetro adicional para excluir/incluir propiedades heredadas, en ese caso se utilizaría hasOwnProperty en lugar de simplemente el bucle for –

Respuesta

3

Corrección: debe marcar myObject.hasOwnProperty(key) en cada iteración, porque puede haber atributos heredados. Por ejemplo, si hace esto antes del ciclo Object.prototype.test = 'test', también se contará test.

Y hablando de su pregunta: simplemente puede definir una función de ayuda, si la velocidad no importa. Después de todo, definimos ayudantes para la función de recorte y otras cosas simples. Una gran cantidad de Javascript es "una especie de rotonda y hacky" :)

actualización
ejemplo Fracaso, conforme a lo solicitado.

Object.prototype.test = 'test'; 
var x = {}; 
x['a'] = 1; 
x['b'] = 2; 

El número devuelto será 3.

+0

El objeto se crea con 'myObject = {}' y luego se le agregan propiedades con 'myObject [key] = value' donde' key' es siempre una cadena. Entonces, creo que eso no sería una preocupación en este caso. – MatrixFrog

+0

@MatrixFrog Oh, ¿en serio? :) No importa qué tipo sea 'clave'. Agregué un ejemplo para aclarar el punto. –

+0

Por cierto, Anurag presiona el mismo punto en su respuesta (el comentario allí) –

0

usted podría también acaba de hacer myObject.length (en matrices)

importa, ven esto: JavaScript object size

+1

No está preguntando acerca de las matrices o de un 'sizeof'. Él quiere la cantidad de mapeos (pares clave-valor) en un objeto. –

+0

'myObject.length' fue mi primer pensamiento, pero sí, solo funciona para arreglos. – MatrixFrog

+0

BTW, el enlace que proporcione es SIZEOF, p. Ej. número de bytes utilizados. OP quiere saber el número de pares clave-valor en un objeto. (Casi hice -1 porque esta no es una respuesta a la pregunta; sin embargo, el enlace es interesante, incluso si se trata de un tema diferente.) – ToolmakerSteve

0

Eso es todo lo que puede hacer. Claramente, los objetos de JavaScript no están diseñados para esto. Y esto solo le dará la cantidad de propiedades enumerables. Pruebe getObjectSize(Math).

13

Existe una manera más fácil spec'da en ECMAScript 5.

Object.keys(..) devuelve una matriz de todas las claves definidas en el objeto. Se puede invocar longitud sobre eso. Tratan en Chrome:

Object.keys({a: 1, b: 2}).length; // 2 

Tenga en cuenta que todos los objetos son básicamente pares clave/valor en JavaScript, y también son muy extensible. Puede ampliar el Object.prototype con un método size y obtener el recuento allí. Sin embargo, una solución mucho mejor es crear una interfaz de tipo HashMap o usar una de las muchas implementaciones existentes, y definir size en ella. He aquí una pequeña aplicación:

function HashMap() {} 

HashMap.prototype.put = function(key, value) { 
    this[key] = value; 
}; 

HashMap.prototype.get = function(key) { 
    if(typeof this[key] == 'undefined') { 
     throw new ReferenceError("key is undefined"); 
    } 
    return this[key]; 
}; 

HashMap.prototype.size = function() { 
    var count = 0; 

    for(var prop in this) { 
     // hasOwnProperty check is important because 
     // we don't want to count properties on the prototype chain 
     // such as "get", "put", "size", or others. 
     if(this.hasOwnProperty(prop) { 
      count++; 
     } 
    } 

    return count; 
}; 

uso como (example):

var map = new HashMap(); 
map.put(someKey, someValue); 
map.size(); 
+0

solo devuelven las claves Enumerable, hasOwnProperty. –

+0

"TypeError: Object.keys no es una función". Supongo que debería haber mencionado que estoy trabajando en una extensión de Firefox, así que si no funciona en Firefox, entonces es bastante inútil para mí. Aún así, buena información para el futuro. ¡Gracias! – MatrixFrog

+0

@Matthew - sí, es por eso que dije * definido en el objeto * y sí la enumerabilidad también es importante, pero eso es lo que 'for..in' también devolverá, así que lo dejé fuera de la discusión. @MatrixFrog - Debería venir en Firefox 4, y siempre se puede definir un tipo de objeto personalizado con un método de tamaño, como en el ejemplo anterior. – Anurag

Cuestiones relacionadas