Longitud de un objeto JavaScript


Si tengo un objeto JavaScript, diga

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

¿Hay una forma incorporada o aceptada de mejores prácticas para obtener la longitud de este objeto?

Author: Gareth Simpson, 2008-08-07

30 answers

La respuesta más robusta (es decir, que captura la intención de lo que está tratando de hacer mientras causa el menor número 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
var size = Object.size(myArray);

Hay una especie de convención en JavaScript que no agrega cosas a Object.prototype, porque puede romper enumeraciones en varias bibliotecas. Sin embargo, agregar métodos al objeto generalmente es seguro.


Aquí hay una actualización a partir 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() 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 que Object.keys() ahora está integrado.

Edit : Los objetos pueden tener propiedades simbólicas que no se pueden devolver a través de Object.método clave. Así que la respuesta sería incompleta sin mencionarlos.

Se agregó el tipo de símbolo al lenguaje para crear identificadores únicos para las propiedades de los objetos. El principal beneficio del tipo de símbolo es la prevención de sobrescribir.

Object.keys o Object.getOwnPropertyNames no funciona para propiedades simbólicas. Para devolverlos necesita 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
 2082
Author: SnnSnn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-15 21:48:10

Si sabe que no tiene que preocuparse por hasOwnProperty cheques, puede hacer esto muy simplemente:

Object.keys(myArray).length
 1442
Author: aeosynth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-21 20:12:12

Actualizado: Si estás usando Subrayado.js (recomendado, es ligero!), entonces solo puede hacer

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

Si no es, y no quiere perder el tiempo con las propiedades de los objetos por cualquier razón, y ya está utilizando jQuery, un plugin 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;
};
 256
Author: ripper234,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-08 10:30:58

Usa algo tan simple como:

Object.keys(obj).length

No tiene que ser difícil y definitivamente no requiere otra función para lograr.

 157
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-17 18:30:01

Aquí está la solución más cross-browser.

Esto es mejor que la respuesta aceptada porque usa Objeto nativo.llaves 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;
 45
Author: Joon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-01 16:12:06

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

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

 29
Author: jj33,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-17 18:27:26

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
 26
Author: venkat7668,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-06 19:43:01

Para no meterse con el prototipo u otro código, puede construir y extender 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 en el método length.

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

 21
Author: DanMan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-08 01:37:04

He aquí cómo y no se olvide de comprobar que la propiedad no está en la cadena de prototipos:

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;
 15
Author: doekman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-23 23:28:42

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

Ver 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);
 14
Author: Ally,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-02 09:01:07

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

 13
Author: Jānis Elmeris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-29 13:41:54

Uso:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)
 13
Author: Mahendra Kulkarni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-17 18:36:54

Simplemente use esto para obtener el length:

Object.keys(myObject).length
 12
Author: saurabhgoyal795,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-04 08:27:18

@palmsey: Para ser justos con el OP, los documentos de javascript en realidad se refieren explícitamente al uso de variables de tipo Object de esta manera como "matrices asociativas".

Y para ser justos con @palmsey, estaba en lo cierto, no son matrices asociativas, son definitivamente objetos :) - haciendo el trabajo de una matriz asociativa. Pero en cuanto al punto más amplio, definitivamente parece tener el derecho de ello de acuerdo con este artículo bastante bueno que encontré:

JavaScript "Matrices Asociativas" Consideradas Dañinas

Pero de acuerdo con todo esto, ¿no es la respuesta aceptada una mala práctica?

Especifique una función prototype size() para Object

Si se ha añadido algo más al Objeto .prototipo, entonces 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 esa respuesta deba ser la aceptada, ya que no se puede confiar en que funcione si tiene cualquier otro código en ejecución en el mismo contexto de ejecución. Para hacerlo de una manera robusta, seguramente tendría que definir el método de tamaño dentro de myArray y comprobar el tipo de los miembros a medida que se itera a través de ellos.

 11
Author: Polsonby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:58

El más simple es Objeto.keys (myObject).longitud

 10
Author: Tamesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-21 02:25:54

¿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--; }}
}
 9
Author: Jerry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-24 14:26:28

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

 9
Author: abo-elleef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-17 18:28:53

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

// 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 su controlador:

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

O, en su opinión:

<any ng-expression="object | lengthOfObject"></any>
 9
Author: pcnate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-17 18:33:46

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

var myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3
 7
Author: Oriol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-18 18:16:07

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.

 6
Author: wade harrell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-07 10:54:43

Si no le importa admitir Internet Explorer 8 o inferior, puede obtener fácilmente el número de propiedades de un objeto aplicando los siguientes dos pasos:

  1. Ejecutar Object.keys() para obtener una matriz que contiene los nombres de sólo aquellas propiedades que son enumerable o Object.getOwnPropertyNames() si desea incluir también los nombres de las propiedades que no son enumerables.
  2. Obtener 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 usar 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

Ver también este Violín para una demostración.

 6
Author: John Slegers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-18 00:19:08

Esto funciona para mí:

var size = Object.keys(myObj).length;
 6
Author: Giovanni Gianni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-06 09:34:40

Aquí hay una versión diferente de la respuesta de James Cogan. En lugar de pasar un argumento, simplemente haga un prototipo de la clase Object y haga que el código sea 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;

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

 5
Author: Sherzod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-26 23:47:45

Simplemente puede usar Object.keys(obj).length en cualquier objeto para obtener su longitud. Objeto.keys devuelve un array que contiene todo el objeto keys (propiedades) que puede ser útil para encontrar la longitud de ese objeto usando la longitud del array correspondiente. Incluso puede escribir una función para esto. Vamos a obtener creativo y escribir un método para él 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
Author: WEB_UI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-12 02:09:14

La forma más simple es así

Object.keys(myobject).length

Donde myobject es el objeto de lo que desea la longitud

 4
Author: Mithu A Quayium,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-30 15:41:40

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

 3
Author: Pian0_M4n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-27 09:05:26
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Objeto.valores (myObject).longitud
  2. Objeto.entradas (myObject).longitud
  3. Objeto.keys (myObject).longitud
 3
Author: tdjprog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-05 23:45:02

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

Object.size = (obj) ->
  size = 0
  size++ for own key of obj
  size
 2
Author: Eric Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-06 19:44:08

Propiedad

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

Use

var o = {a: 1, b: 2, c: 3};
alert(o.length); // <-- 3
o['foo'] = 123;
alert(o.length); // <-- 4
 2
Author: Eduardo Cuomo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-06 19:10:35

Como la mayoría de los problemas de JavaScript, hay muchas soluciones. Podrías ampliar el Objeto que para bien o para mal funciona como el Diccionario de muchos otros idiomas (+ciudadanos de primera clase). No hay nada malo con eso, pero otra opción es construir un nuevo Objeto que satisfaga sus necesidades específicas.

function uberject(obj){
    this._count = 0;
    for(var param in obj){
        this[param] = obj[param];
        this._count++;
    }
}

uberject.prototype.getLength = function(){
    return this._count;
};

var foo = new uberject({bar:123,baz:456});
alert(foo.getLength());
 2
Author: Ron Sims II,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-19 06:27:26