Longitud de un objeto JavaScript

Tengo un objeto JavaScript. ¿Existe una forma de práctica recomendada incorporada o aceptada para obtener la longitud de este objeto?

const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

preguntado el 07 de agosto de 08 a las 17:08

Los literales de objeto en javascript son por defecto matrices asociativas, por ejemplo, object.propertyName.propertyValue es el mismo que object [propertyName] [propertyValue] -

Se agregó una línea en Underscore.js que hace esto: stackoverflow.com/a/11346637/11236 -

Una vez que la línea de respuesta es use Object.keys (myArray) .length como dijo @aeosynth. -

ok, que tal Object.keys(obj).length -

¿Por qué no es válido object.length? Devuelve el resultado correcto para mí. -

30 Respuestas

La respuesta más sólida (es decir, que captura la intención de lo que está tratando de hacer mientras causa la menor cantidad de errores) sería:

Object.size = function(obj) {
  var size = 0,
    key;
  for (key in obj) {
    if (obj.hasOwnProperty(key)) size++;
  }
  return size;
};

// Get the size of an object
const myObj = {}
var size = Object.size(myObj);

Hay una especie de convención en JavaScript que no agregue cosas a Object.prototype, porque puede romper enumeraciones en varias bibliotecas. Sin embargo, agregar métodos a Object suele ser seguro.


Aquí hay una actualización de 2016 y despliegue generalizado de ES5 y más allá. Para IE9 + y todos los demás navegadores modernos compatibles con ES5 +, puede usar Object.keys() por lo que el código anterior simplemente se convierte en:

var size = Object.keys(myObj).length;

Esto no tiene que modificar ningún prototipo existente ya que Object.keys() ahora está integrado.

Editar: Los objetos pueden tener propiedades simbólicas que no se pueden devolver mediante el método Object.key. Entonces la respuesta estaría incompleta sin mencionarlos.

El tipo de símbolo se agregó al lenguaje para crear identificadores únicos para las propiedades del objeto. El principal beneficio del tipo Símbolo es la prevención de sobrescrituras.

Object.keys or Object.getOwnPropertyNames no funciona para propiedades simbólicas. Para devolverlos necesitas usar Object.getOwnPropertySymbols.

var person = {
  [Symbol('name')]: 'John Doe',
  [Symbol('age')]: 33,
  "occupation": "Programmer"
};

const propOwn = Object.getOwnPropertyNames(person);
console.log(propOwn.length); // 1

let propSymb = Object.getOwnPropertySymbols(person);
console.log(propSymb.length); // 2

Respondido el 09 de enero de 21 a las 17:01

@Tres: su código puede romperse si alguien viene y anula la propiedad 'size' sin saber que ya lo declaró en algún lugar del código, por lo que siempre vale la pena verificar si ya está definido vsync

@vsync Tienes mucha razón. Siempre se deben implementar las comprobaciones de cordura necesarias :) - Tres

¿Por qué todos ignoran esto? Object.keys(obj).length - Muhammad Umer

@MuhammadUmer Probablemente porque ese método ni siquiera existía cuando se escribió esta respuesta. Incluso hoy en día, su uso probablemente requiera un polyfill para navegadores antiguos. - Chris Hayes

@stonyau IE8, IE9, IE10 son navegadores muertos que no reciben soporte de Microsoft. El usuario de IE8, IE9, IE10 recibe una notificación de Microsoft, que usa un navegador antiguo no compatible y debe esperar que las cosas no funcionen para ellos. support.microsoft.com/en-us/kb/3123303 - Lukas Liesis

Si sabes que no tienes que preocuparte por hasOwnProperty cheques, puede hacer esto de manera muy simple:

Object.keys(myArray).length

Respondido el 21 de junio de 17 a las 21:06

¿Por qué no? por lo que sé, es un estándar: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… - vsync

No es un universal implementado método, pero puede comprobar qué navegador lo admite con Esta mesa. - eosintetizador

es hora de cambiar a firefox = desafortunadamente, cambiar no significa que los usuarios de su sitio web ... - mdup

@ ripper234 sin soporte de IE = tiempo para polyfill - Juan Dvorak

@ ripper234 que se preocupa por IE, nadie debería preocuparse por los estándares de IE, solo los estándares. los usuarios quieren usar IE, entonces no navegarán por mi sitio web. Ya no me importa. los desarrolladores no deben rellenar los estándares ni los estándares elaborados por, por ejemplo, "desarrolladores" - Albanx

Actualizado: Si está usando Underscore.js (recomendado, ¡es liviano!), entonces puedes hacer

_.size({one : 1, two : 2, three : 3});
=> 3

Si no, y no quiere perder el tiempo con las propiedades del objeto por alguna razón, y ya está usando jQuery, un complemento es igualmente accesible:

$.assocArraySize = function(obj) {
    // http://stackoverflow.com/a/6700/11236
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

Respondido 08 Jul 12, 11:07

_.size() fue la solución perfecta para mi meteoro proyecto, que tiene soporte de underscore.js. - tokiovariable

Utilizo guión bajo y esta publicación solo me recordó que no lo estoy usando lo suficiente en este proyecto. Si maneja objetos, debe tener undercore.js disponible. - jbolanos

Guión bajo> (todo - ['guión bajo']) - Rayjax

subrayadojs, cosas que deberían estar bajo js :) - Minhajul

@Babydead para distinguir las propiedades reales del objeto frente a las heredadas. desarrollador.mozilla.org/en/docs/Web/JavaScript/Reference/… - ripper234

Esta es la solución más entre navegadores.

Esto es mejor que la respuesta aceptada porque usa Object.keys nativos si existe. Por lo tanto, es el más rápido para todos los navegadores modernos.

if (!Object.keys) {
    Object.keys = function (obj) {
        var arr = [],
            key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                arr.push(key);
            }
        }
        return arr;
    };
}

Object.keys(obj).length;

Respondido el 01 de Septiembre de 13 a las 17:09

Object.keys() devuelve una matriz que contiene los nombres de solo aquellas propiedades que son enumerables. Si desea una matriz con TODAS las propiedades, debe usar Object.getOwnPropertyNames() en lugar. Ver desarrollador.mozilla.org/en/docs/Web/JavaScript/Reference/… - Juan Slegers

No soy un experto en JavaScript, pero parece que tendrías que recorrer los elementos y contarlos, ya que Object no tiene un método de longitud:

var element_count = 0;
for (e in myArray) {  if (myArray.hasOwnProperty(e)) element_count++; }

@palmsey: Para ser justos con el OP, la documentación de JavaScript en realidad se refiere explícitamente al uso de variables de tipo Object de esta manera como "matrices asociativas".

Respondido el 17 de Septiembre de 16 a las 19:09

No funcionará, porque también contará los métodos que se agregan a través del prototipo. - Lajos Meszaros

Este método obtiene todos los nombres de propiedad de su objeto en una matriz, por lo que puede obtener la longitud de esa matriz que es igual a la longitud de las claves de su objeto.

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2

Respondido 06 Feb 15, 19:02

El método de claves de @PatrickRoberts no devuelve propiedades de la cadena de prototipos. Entonces, ¿por qué la necesidad de hasOwnProperty aquí? También getOwnProperty devolverá propiedades ocultas, ya que la longitud está en la matriz, etc. Muhammad Umer

Simplemente use esto para obtener el length:

Object.keys(myObject).length

Respondido 04 Abr '18, 09:04

por favor explique en qué se diferencia su respuesta de stackoverflow.com/a/6700/8632727 - patata

Bien, siempre es mejor nombrar sus variables de acuerdo con lo que realmente son. Hace que su código sea más legible para otros desarrolladores. - Barry Michael Doyle

Antes de la edición de "myArray" -> "myObject", esto era idéntico a la segunda respuesta más votada. - Yunnosch

Igual que las respuestas anteriores. - Alberto Pérez

Para no meterse con el prototipo u otro código, puede crear y ampliar su propio objeto:

function Hash(){
    var length=0;
    this.add = function(key, val){
         if(this[key] == undefined)
         {
           length++;
         }
         this[key]=val;
    }; 
    this.length = function(){
        return length;
    };
}

myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2

Si siempre usa el método add, la propiedad length será correcta. Si le preocupa que usted u otros se olviden de usarlo, también puede agregar el contador de propiedades que los demás han publicado al método de longitud.

Por supuesto, siempre puede sobrescribir los métodos. Pero incluso si lo hace, su código probablemente fallará notablemente, lo que facilitará la depuración. ;)

Respondido 08 ago 15, 02:08

Creo que esta es la mejor solución, ya que no requiere bucle con 'for', lo que podría ser costoso si la matriz es grande. emeka mba

A continuación, le indicamos cómo y no olvide verificar que la propiedad no esté en la cadena del prototipo:

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;

contestado el 24 de mayo de 12 a las 00:05

Podemos encontrar la longitud de Object usando:

const myObject = {};
console.log(Object.values(myObject).length);

Respondido el 09 de enero de 21 a las 13:01

Aquí hay una solución completamente diferente que solo funcionará en navegadores más modernos (Internet Explorer 9+, Chrome, Firefox 4+, Opera 11.60+ y Safari 5.1+)

Vea este jsFiddle.

Configure su clase de matriz asociativa

/**
 * @constructor
 */
AssociativeArray = function () {};

// Make the length property work
Object.defineProperty(AssociativeArray.prototype, "length", {
    get: function () {
        var count = 0;
        for (var key in this) {
            if (this.hasOwnProperty(key))
                count++;
        }
        return count;
    }
});

Ahora puede usar este código de la siguiente manera ...

var a1 = new AssociativeArray();
a1["prop1"] = "test";
a1["prop2"] = 1234;
a1["prop3"] = "something else";
alert("Length of array is " + a1.length);

Respondido 10 Jul 20, 19:07

Creo que eso no es seguro. Por ejemplo, no puede tener un elemento con una clave de "longitud", la declaración a1 ["longitud"] = "Hola mundo"; no almacena la entrada. También la declaración a1 ["hasOwnProperty"] = "algún objeto"; rompe totalmente la función - Panos Theof

@PanosTheof No creo que quieras que almacene el valor si usas el length propiedad, cualquier código que lo usara tendría que asegurarse de que no intentara almacenar contra length, pero supongo que sería lo mismo si también fuera una matriz estándar. Primordial hasOwnProperty en cualquier objeto probablemente produciría un resultado no deseado. - Ally

<script>
myObj = {"key1" : "Hello", "key2" : "Goodbye"};
var size = Object.keys(myObj).length;
console.log(size);
</script>

<p id="myObj">The number of <b>keys</b> in <b>myObj</b> are: <script>document.write(size)</script></p>

Esto funciona para mi:

var size = Object.keys(myObj).length;

respondido 22 mar '19, 13:03

Si necesita una estructura de datos asociativa que exponga su tamaño, mejor use un mapa en lugar de un objeto.

const myMap = new Map();

myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);

console.log(myMap.size); // 3

Respondido el 24 de Septiembre de 20 a las 15:09

En algunos casos, es mejor almacenar el tamaño en una variable separada. Especialmente, si está agregando a la matriz un elemento en un lugar y puede incrementar fácilmente el tamaño. Obviamente, funcionaría mucho más rápido si necesita verificar el tamaño con frecuencia.

Respondido 29 Jul 11, 14:07

Uso:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)

Respondido el 17 de Septiembre de 16 a las 19:09

La forma más sencilla es así:

Object.keys(myobject).length

Donde myobject es el objeto de lo que desea la longitud.

Respondido 10 Jul 20, 19:07

Esto parece ser solo una repetición de esta respuesta existente. - Pang

@Pang estuvo de acuerdo, y no proporciona ningún contexto adicional como lo hacen otras respuestas. - Místico

Utiliza Object.keys(myObject).length para obtener la longitud del objeto / matriz

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

console.log(Object.keys(myObject).length); //3

Respondido el 09 de enero de 21 a las 17:01

@palmsey: Para ser justos con el OP, la documentación de JavaScript en realidad se refiere explícitamente al uso de variables de tipo Object de esta manera como "matrices asociativas".

Y para ser justos con @palmsey, tenía bastante razón. No son matrices asociativas; definitivamente son objetos :) - haciendo el trabajo de una matriz asociativa. Pero en lo que respecta al punto más amplio, definitivamente parece que tiene el derecho de hacerlo de acuerdo con este artículo bastante bueno que encontré:

Las "matrices asociativas" de JavaScript se consideran perjudiciales

Pero según todo esto, la respuesta aceptada en sí mismo es una mala práctica?

Especificar una función de tamaño de prototipo () para Objeto

Si se ha agregado algo más a Object .prototype, el código sugerido fallará:

<script type="text/javascript">
Object.prototype.size = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
Object.prototype.size2 = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
</script>

No creo que la respuesta deba ser la aceptada, ya que no se puede confiar en que funcione si tiene otro código ejecutándose en el mismo contexto de ejecución. Para hacerlo de manera robusta, seguramente necesitará definir el método de tamaño dentro de myArray y verificar el tipo de miembros a medida que los recorre.

Respondido 10 Jul 20, 19:07

¿Qué pasa con algo como esto?

function keyValuePairs() {
    this.length = 0;
    function add(key, value) { this[key] = value; this.length++; }
    function remove(key) { if (this.hasOwnProperty(key)) { delete this[key]; this.length--; }}
}

Respondido 24 ago 11, 15:08

Si tenemos el hash

hash = {"a": "b", "c": "d"};

podemos obtener la longitud usando la longitud de las claves, que es la longitud del hash:

claves (hash) .length

Respondido el 17 de Septiembre de 16 a las 19:09

Esta es una gran respuesta, sin embargo, no puedo encontrar ninguna documentación para esta función de teclas. Así que no puedo confiar en la compatibilidad con varios navegadores. - químico

Desafortunadamente, ¡esta no es una respuesta tan buena como pensé al principio! Resulta que la función de las teclas solo está disponible en las consolas web Chrome y Firefox. Si coloca este código en un script, fallará con Uncaught ReferenceError: las claves no están definidas - químico

¿En qué se diferencia esto de la respuesta de aeosynth? - Pedro Mortensen

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Object.values ​​(myObject) .length
  2. Object.entries (myObject) .length
  3. Object.keys (myObject) .length

Respondido 06 Abr '18, 00:04

¿Cuál es más rápido entre los anteriores 3. - siluveru kiran kumar

Object.values ​​(myObject) .length - tdjprog

como podemos decir eso Object.values ​​(myObject) .length es más rápido, ¿hay algún ejemplo? Gracias, @tdjprog - siluveru kiran kumar

solo prueba esto en la consola:var myObject = {}; for (let i=0; i<10000000; i++) myObject[i] = i; - tdjprog

por qué Object.values ​​(myObject) .length más rápido, donde como Object.entries (myObject) .length no dando salida incluso después de algún tiempo, ¿cuál es la razón aquí? Gracias @tdjprog - siluveru kiran kumar

const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

console.log(Object.keys(myObject).length)

// o/p 3

Respondido el 11 de enero de 20 a las 12:01

¿Qué "o / p 3" ¿media? - Pedro Mortensen

Una explicación de esta respuesta estaría en orden. - Pedro Mortensen

Además, ¿en qué se diferencia de las respuestas anteriores, p. Ej. la respuesta de shaheb? - Pedro Mortensen

Si está utilizando AngularJS 1.x puede hacer las cosas a la manera AngularJS creando un filtro y usando el código de cualquiera de los otros ejemplos, como el siguiente:

// Count the elements in an object
app.filter('lengthOfObject', function() {
  return function( obj ) {
    var size = 0, key;
    for (key in obj) {
      if (obj.hasOwnProperty(key)) size++;
    }
   return size;
 }
})

Uso

En tu controlador:

$scope.filterResult = $filter('lengthOfObject')($scope.object)

O en tu opinión:

<any ng-expression="object | lengthOfObject"></any>

Respondido el 17 de Septiembre de 16 a las 19:09

El OP no ha solicitado una versión de AngularJS. Esta no es una respuesta válida a la pregunta. - francisco hodge

Una variación de algunos de los anteriores es:

var objLength = function(obj){    
    var key,len=0;
    for(key in obj){
        len += Number( obj.hasOwnProperty(key) );
    }
    return len;
};

Es una forma un poco más elegante de integrar hasOwnProp.

Respondido 07 Oct 14, 11:10

Si no le importa admitir Internet Explorer 8 o versiones anteriores, puede obtener fácilmente la cantidad de propiedades en un objeto aplicando los siguientes dos pasos:

  1. Ejecutar cualquiera Object.keys() para obtener una matriz que contenga los nombres de solo aquellas propiedades que son enumerable or Object.getOwnPropertyNames() si desea incluir también los nombres de propiedades que no son enumerables.
  2. Consiguir el .length propiedad de esa matriz.

Si necesita hacer esto más de una vez, puede envolver esta lógica en una función:

function size(obj, enumerablesOnly) {
    return enumerablesOnly === false ?
        Object.getOwnPropertyNames(obj).length :
        Object.keys(obj).length;
}

Cómo utilizar esta función en particular:

var myObj = Object.create({}, {
    getFoo: {},
    setFoo: {}
});
myObj.Foo = 12;

var myArr = [1,2,5,4,8,15];

console.log(size(myObj));        // Output : 1
console.log(size(myObj, true));  // Output : 1
console.log(size(myObj, false)); // Output : 3
console.log(size(myArr));        // Output : 6
console.log(size(myArr, true));  // Output : 6
console.log(size(myArr, false)); // Output : 7

Véase también este violín para una demostración

Respondido el 18 de Septiembre de 16 a las 01:09

Aquí hay una versión diferente de la respuesta de James Cogan. En lugar de pasar un argumento, simplemente prototipo de la clase Object y haga el código más limpio.

Object.prototype.size = function () {
    var size = 0,
        key;
    for (key in this) {
        if (this.hasOwnProperty(key)) size++;
    }
    return size;
};

var x = {
    one: 1,
    two: 2,
    three: 3
};

x.size() === 3;

ejemplo de jsfiddle: http://jsfiddle.net/qar4j/1/

Respondido el 27 de junio de 13 a las 00:06

Object.prototype - mala idea. - Dziad Borowy

@tborychowski, ¿podrías explicar por qué? - Mohamad

aquí hay un artículo: bit.ly/1droWrG. No estoy diciendo que no deba hacerse, solo que debes conocer todas las repercusiones antes de hacer esto. - Dziad Borowy

Si va a extender prototipos incorporados o rellenar una propiedad (es decir, parche de mono), hágalo correctamente: para compatibilidad con versiones posteriores, verifique si la propiedad existe primero, luego haga que la propiedad no sea enumerable para que las propias claves de los objetos construidos no están contaminados. Para métodos use real métodos. Mi recomendación: sigue estos ejemplos que demuestran cómo agregar un método que se comporte lo más parecido posible a los métodos integrados. - Sebastian simon

Simplemente puede usar Object.keys(obj).length en cualquier objeto para obtener su longitud. Object.keys devuelve una matriz que contiene todo el objeto claves (propiedades) que pueden resultar útiles para encontrar la longitud de ese objeto utilizando la longitud de la matriz correspondiente. Incluso puedes escribir un función para esto. Vamos a llegar creativo y escribe un Método para ello también (junto con una propiedad getter más conveniente):

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

console.log(objLength({a:1, b:"summit", c:"nonsense"}));

// Works perfectly fine
var obj = new Object();
obj['fish'] = 30;
obj['nullified content'] = null;
console.log(objLength(obj));

// It also works your way, which is creating it using the Object constructor
Object.prototype.getLength = function() {
   return Object.keys(this).length;
}
console.log(obj.getLength());

// You can also write it as a method, which is more efficient as done so above

Object.defineProperty(Object.prototype, "length", {get:function(){
    return Object.keys(this).length;
}});
console.log(obj.length);

// probably the most effictive approach is done so and demonstrated above which sets a getter property called "length" for objects which returns the equivalent value of getLength(this) or this.getLength()

Respondido 12 Oct 16, 03:10

¿En qué se diferencia esto de la respuesta de aeosynth? - Pedro Mortensen

Es porque muestra cómo hacerlo como una función y un método de objeto global (más orientado a objetos y usa alguna forma de encapsulación); sin emabargo la respuesta de aeosynth no lo hace. - Místico

Si va a extender prototipos incorporados o rellenar una propiedad (es decir, parche de mono), hágalo correctamente: para compatibilidad con versiones posteriores, verifique si la propiedad existe primero, luego haga que la propiedad no sea enumerable para que las propias claves de los objetos construidos no están contaminados. Para métodos use real métodos. Mi recomendación: sigue estos ejemplos que demuestran cómo agregar un método que se comporte lo más parecido posible a los métodos integrados. - Sebastian simon

Además, ¿cómo es "más eficiente" escribir un método? - Sebastian simon

Siempre puedes hacer Object.getOwnPropertyNames(myObject).length para obtener el mismo resultado que [].length daría para una matriz normal.

Respondido el 27 de Septiembre de 17 a las 10:09

Object.keys() devuelve una matriz que contiene los nombres de solo aquellas propiedades que son enumerables. Si desea una matriz con TODAS las propiedades, debe usar Object.getOwnPropertyNames() en lugar. Ver desarrollador.mozilla.org/en/docs/Web/JavaScript/Reference/… - Juan Slegers

¿En qué se diferencia esto de la respuesta de aeosynth? - Pedro Mortensen

Una buena manera de lograr esto (solo Internet Explorer 9+) es definir un captador mágico en la propiedad length:

Object.defineProperty(Object.prototype, "length", {
    get: function () {
        return Object.keys(this).length;
    }
});

Y puedes usarlo así:

var myObj = { 'key': 'value' };
myObj.length;

Daría 1.

Respondido 10 Jul 20, 19:07

Dejando a un lado los argumentos en contra de la modificación del prototipo, personalmente NUNCA he tenido un error causado por él y para mí es uno de los puntos fuertes de JavaScript. - macrohombre

A continuación se muestra una versión de la respuesta de James Coglan en CoffeeScript para aquellos que han abandonado JavaScript puro :)

Object.size = (obj) ->
  size = 0
  size++ for own key of obj
  size

Respondido 06 Oct 14, 20:10

Probablemente quisiste decir size++ for own key of obj (own key siendo azúcar de sintaxis en CoffeeScript). Utilizando hasOwnProperty directamente del objeto es peligroso, ya que se rompe cuando el objeto realmente tiene tal propiedad. - Konrad Borowski

El OP no solicitó una versión de CoffeeScript, ni está etiquetado como tal. Esta no es una respuesta válida a la pregunta. - francisco hodge

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.