Longitud de un objeto JavaScript

2673

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;
13
  • 17
    Los literales de objeto en javascript son por defecto matrices asociativas, por ejemplo, object.propertyName.propertyValue es el mismo que object [propertyName] [propertyValue]neitony 13/02/11 a las 16:19
  • 7
    Se agregó una línea en Underscore.js que hace esto: stackoverflow.com/a/11346637/11236ripper234 8 de julio de 2012 a las 10:31
  • 37
    Una vez que la línea de respuesta es use Object.keys (myArray) .length como dijo @aeosynth. Ranadheer Reddy 22 de junio de 2013 a las 7:50
  • 92
    ok, que talObject.keys(obj).lengthMuhammad Umer 25/02/15 a las 0:14
  • 6
    ¿Por qué no es válido object.length? Devuelve el resultado correcto para mí. Adrian M 26/06/2016 a las 17:01
2874

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 de que no agregas 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 a partir de 2016 y la implementación generalizada de ES5 y más allá. Para IE9 + y todos los demás navegadores modernos con capacidad para ES5 +, puede usarlo Object.keys()para que el código anterior se convierta en:

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

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

Editar : los objetos pueden tener propiedades simbólicas que no se pueden devolver a través del 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.keyso Object.getOwnPropertyNamesno funciona para propiedades simbólicas. Para devolverlos es necesario utilizar 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
dieciséis
  • 66
    @Tres: su código puede romperse si alguien viene y anula la propiedad 'tamaño' sin saber que ya lo declaró en algún lugar del código, por lo que siempre vale la pena verificar si ya está definidovsync 14/06/11 a las 11:30
  • 19
    @vsync Tienes mucha razón. Siempre se deben implementar las comprobaciones de cordura necesarias :)Tres 24/06/11 a las 2:03
  • 151
    ¿Por qué todos ignoran estoObject.keys(obj).lengthMuhammad Umer 25/02/15 a las 0:14
  • 36
    @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 9 de mayo de 2015 a las 1:53
  • 22
    @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 de que usa un navegador antiguo no compatible y debe esperar que las cosas no funcionen para ellos. support.microsoft.com/en-us/kb/3123303Lukas Liesis 19 de enero de 2016 a las 9:08
1912

Si sabe que no tiene que preocuparse por los hasOwnPropertycheques, puede hacerlo de manera muy simple:

Object.keys(myArray).length
18
  • 25
    ¿Por qué no? por lo que sé, es un estándar: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…vsync 6/06/11 a las 11:51
  • 108
    No es un método implementado universalmente , pero puede verificar qué navegador lo admite con esta tabla . aeosynth 6/06/11 a las 19:08
  • 25
    es hora de cambiar a firefox = desafortunadamente, cambiar no significa que los usuarios de su sitio web ...mdup 13/08/12 a las 11:25
  • 87
    @ ripper234 sin soporte de IE = tiempo para polyfillJohn Dvorak 13/12/12 a las 6:27
  • 21
    @ 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 21 mar '14 a las 15:17
301

Actualizado : si está usando Underscore.js (recomendado, ¡es liviano!), Entonces puede hacerlo

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

Si no es así , y no quiere perder el tiempo con las propiedades del objeto por cualquier motivo, 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;
};
6
  • 8
    _.size()fue la solución perfecta para mi proyecto Meteor , que tiene soporte para underscore.js. tokyovariable 1 de agosto de 2013 a las 17:05
  • 4
    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 20/11/2013 a las 20:51
  • 3
    Guión bajo> (todo - ['guión bajo'])Rayjax 11/04/2014 a las 8:13
  • subrayadojs, cosas que deberían estar bajo js :)minhaj 30 oct 2015 a las 10:02
  • 1
    @Babydead para distinguir las propiedades reales del objeto frente a las heredadas. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…ripper234 12 feb 2017 a las 19:56
63

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;
1
39

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".

1
  • 8
    No funcionará, porque también contará los métodos que se agregan a través del prototipo. Lajos Mészáros 8/10/2013 a las 11:32
35

Simplemente use esto para obtener length:

Object.keys(myObject).length
4
  • 12
    explique en qué se diferencia su respuesta de stackoverflow.com/a/6700/8632727Patata 13/02/18 a las 13:04
  • 1
    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 4 de abril de 2018 a las 8:26
  • 6
    Antes de la edición de "myArray" -> "myObject", esto era idéntico a la segunda respuesta más votada. Yunnosch 25 de mayo de 2018 a las 6:44
  • 4
    Igual que las respuestas anteriores. Alberto Perez 27/08/19 a las 9:47
33

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
1
  • 1
    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 volverá propiedades ocultas, como la longitud está en array etc.Muhammad Umer 26/02/15 a las 16:07
25

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. ;)

1
  • 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 grandeEmeka Mbah 1 de junio de 2016 a las 19:53
21

Podemos encontrar la longitud de Object usando:

const myObject = {};
console.log(Object.values(myObject).length);
1
  • Teóricamente, este sería más lento que el método de "claves" si tiene valores largos, ya que accede directamente a los valores y luego los cuenta. JSG 6 de junio a las 21:55
20

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++;
17

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);
2
  • 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ónPanos Theof 26/10/2014 a las 11:16
  • 3
    @PanosTheof No creo que quieras que almacene el valor si usaste la lengthpropiedad, cualquier código que lo usara tendría que asegurarse de que no intentara almacenarlo length, pero supongo que sería lo mismo si fuera una matriz estándar también. Anular hasOwnPropertycualquier objeto probablemente produciría un resultado no deseado. Ally 27/10/2014 a las 0:03
17

Úselo Object.keys(myObject).lengthpara 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
16

<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;
16

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
15

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.

0
15

Usar:

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

@palmsey: In fairness to the OP, the JavaScript documentation actually explicitly refer to using variables of type Object in this manner as "associative arrays".

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 de acuerdo con todo esto, ¿ la respuesta aceptada en sí misma es una mala práctica?

Specify a prototype size() function for Object

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 cualquier 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.

13

La forma más sencilla es así:

Object.keys(myobject).length

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

2
  • 4
    Esto parece ser solo una repetición de esta respuesta existente . Pang 15 de noviembre de 2018 a las 3:22
  • @Pang estuvo de acuerdo, y no proporciona ningún contexto adicional como lo hacen otras respuestas. Mystical 21 de enero de 2019 a las 4:23
11

¿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--; }}
}
0
11

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:

keys(hash).length

4
  • 2
    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. chim 3 de septiembre de 2015 a las 9:54
  • 2
    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 definidaschim 3 de septiembre de 2015 a las 10:14
  • stackoverflow.com/questions/32372685/…chim 3 de septiembre de 2015 a las 10:17
  • 1
    ¿En qué se diferencia esto de la respuesta de aeosynth ? Peter Mortensen 17 de septiembre de 2016 a las 18:32
11
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
6
  • 1
    ¿Cuál es más rápido entre los anteriores 3.siluveru kiran kumar 21/06/19 a las 7:23
  • 1
    Object.values ​​(myObject) .lengthtdjprog 1 de julio de 2019 a las 21:11
  • 1
    ¿cómo podemos decir que Object.values ​​(myObject) .length es más rápido hay algún ejemplo Gracias, @tdjprogsiluveru kiran kumar 2 de julio de 2019 a las 7:02
  • 1
    solo prueba esto en la consola:var myObject = {}; for (let i=0; i<10000000; i++) myObject[i] = i;tdjprog 3 de julio de 2019 a las 1:25
  • 1
    por qué Object.values ​​(myObject) .length más rápido, donde como Object.entries (myObject) .length no da salida incluso después de algún tiempo, ¿cuál es la razón aquí? Gracias @tdjprogsiluveru kiran kumar 3 de julio de 2019 a las 7:02
10

Si está utilizando AngularJS 1.x, puede hacer las cosas de 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>
1
  • 4
    El OP no ha solicitado una versión de AngularJS. Esta no es una respuesta válida a la pregunta. Francisco Hodge 4 dic 2015 a las 21:07
9
const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

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

// o/p 3
5
8

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.

8

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. Ejecute Object.keys()para obtener una matriz que contenga solo los nombres de aquellas propiedades que son enumerables o Object.getOwnPropertyNames()si desea incluir también los nombres de las propiedades que no son enumerables.
  2. Obtén la .lengthpropiedad 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

Vea también este Fiddle para una demostración.

6

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/

4
  • 6
    Object.prototype- mala idea. Dziad Borowy 14/10/2013 a las 10:50
  • @tborychowski, ¿podrías explicar por qué? Mohamad 5 mar 14 a las 13:09
  • 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 5 mar 14 a las 15:55
  • 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 los métodos, use métodos reales . Mi recomendación: siga estos ejemplos que demuestran cómo agregar un método que se comporte lo más parecido posible como los métodos integrados. Sebastian Simon 9 de mayo de 2020 a las 9:43
5

Simplemente puede usar Object.keys(obj).lengthen cualquier objeto para obtener su longitud. Object.keys devuelve una matriz que contiene todas las claves de objeto (propiedades) que pueden resultar útiles para encontrar la longitud de ese objeto utilizando la longitud de la matriz correspondiente. Incluso puedes escribir una función para esto. Seamos creativos y escribamos 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()
4
  • 4
    ¿En qué se diferencia esto de la respuesta de aeosynth ? Peter Mortensen 17 de septiembre de 2016 a las 18:39
  • 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 embargo, la respuesta de aeosynth no lo hace. Mystical 18 de septiembre de 2016 a las 1:34
  • 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 los métodos, use métodos reales . Mi recomendación: siga estos ejemplos que demuestran cómo agregar un método que se comporte lo más parecido posible como los métodos integrados. Sebastian Simon 9 de mayo de 2020 a las 9:45
  • Además, ¿cómo es "más eficiente" escribir un método? Sebastian Simon 9 de mayo de 2020 a las 9:46
5

Siempre puede hacer Object.getOwnPropertyNames(myObject).lengthpara obtener el mismo resultado [].lengthque daría para una matriz normal.

2
4

Una buena forma 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.

1
  • 2
    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. MacroMan 13/08/19 a las 9:31
3

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
2
  • 2
    Probablemente quisiste decir size++ for own key of obj( own keysiendo azúcar de sintaxis en CoffeeScript). Usar hasOwnPropertydirectamente desde el objeto es peligroso, ya que se rompe cuando el objeto realmente tiene tal propiedad. Konrad Borowski 1 de septiembre de 2013 a las 10:47
  • 2
    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 4 dic 2015 a las 21:01