¿Cómo enumero las propiedades de un objeto JavaScript? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

¿Cómo enumero las propiedades de un objeto JavaScript?

En realidad quiero enumerar todas las variables definidas y sus valores, pero he aprendido que definir una variable en realidad crea una propiedad de la ventana objeto.

Author: Peter Mortensen, 2008-09-17

14 answers

Bastante simple:

for(var propertyName in myObject) {
   // propertyName is what you want
   // you can get the value like this: myObject[propertyName]
}

Ahora, no obtendrá variables privadas de esta manera porque no están disponibles.


EDIT: @bitwiseplatypus es correcto que a menos que use el método hasOwnProperty(), obtendrá propiedades que se heredan; sin embargo, no se por qué alguien familiarizado con la programación orientada a objetos esperaría algo menos! Por lo general, alguien que menciona esto ha sido sometido a las advertencias de Douglas Crockford sobre esto, que todavía me confunden un trozo. Una vez más, la herencia es una parte normal de los lenguajes OO y, por lo tanto, es parte de JavaScript, a pesar de ser prototípico.

Ahora, dicho esto, hasOwnProperty() es útil para filtrar, pero no necesitamos hacer sonar una advertencia como si hubiera algo peligroso en obtener propiedades heredadas.

EDIT 2: @bitwiseplatypus muestra la situación que ocurriría si alguien agregara propiedades / métodos a sus objetos en un momento posterior a cuando originalmente escribió sus objetos (a través de su prototipo) - si bien es cierto que esto podría causar un comportamiento inesperado, personalmente no lo veo como mi problema por completo. Sólo es cuestión de opinión. Además, ¿qué pasa si diseño cosas de tal manera que use prototipos durante la construcción de mis objetos y aún así tengo código que itera sobre las propiedades del objeto y quiero todas las propiedades heredadas? Yo no usaría hasOwnProperty(). Entonces, digamos, alguien agrega nuevas propiedades más tarde. Es mi culpa si las cosas se comportan mal en ese punto? No lo creo. Creo que esta es la razón por la que jQuery, como ejemplo, ha especificado formas de extender su funcionamiento (a través de jQuery.extend y jQuery.fn.extend).

 746
Author: Jason Bunting,
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 10:31:30

Use un bucle for..in para enumerar las propiedades de un objeto, pero tenga cuidado. La enumeración devolverá propiedades no solo del objeto que se está enumerando, sino también de los prototipos de cualquier objeto padre.

var myObject = {foo: 'bar'};

for (var name in myObject) {
  alert(name);
}

// results in a single alert of 'foo'

Object.prototype.baz = 'quux';

for (var name in myObject) {
  alert(name);
}

// results in two alerts, one for 'foo' and one for 'baz'

Para evitar incluir propiedades heredadas en su enumeración, marque hasOwnProperty():

for (var name in myObject) {
  if (myObject.hasOwnProperty(name)) {
    alert(name);
  }
}

Edit: No estoy de acuerdo con la afirmación de JasonBunting de que no tenemos que preocuparnos por enumerar propiedades heredadas. Hay peligro en enumerar sobre propiedades heredadas que no esperas, porque puede cambiar el comportamiento de tu código.

No importa si este problema existe en otros lenguajes; el hecho es que existe, y JavaScript es particularmente vulnerable ya que las modificaciones al prototipo de un objeto afectan a los objetos secundarios incluso si la modificación tiene lugar después de la instanciación.

Esta es la razón por la que JavaScript proporciona hasOwnProperty(), y esta es la razón por la que debe usarlo para garantizar que el código de terceros (o cualquier otro código que podría modificar un prototipo) no rompe el tuyo. Aparte de agregar algunos bytes adicionales de código, no hay inconveniente en usar hasOwnProperty().

 211
Author: Ryan Grove,
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
2008-09-17 23:02:09

El camino estándar, que ya se ha propuesto varias veces es:

for (var name in myObject) {
  alert(name);
}

Sin embargo, Internet Explorer 6, 7 y 8 tienen un error en el intérprete de JavaScript, que tiene el efecto de que algunas claves no se enumeran. Si ejecuta este código:

var obj = { toString: 12};
for (var name in obj) {
  alert(name);
}

Si alertará "12" en todos los navegadores excepto IE. IE simplemente ignorará esta clave. Los valores clave afectados son:

  • isPrototypeOf
  • hasOwnProperty
  • toLocaleString
  • toString
  • valueOf

To be realmente seguro en IE tienes que usar algo como:

for (var key in myObject) {
  alert(key);
}

var shadowedKeys = [
  "isPrototypeOf",
  "hasOwnProperty",
  "toLocaleString",
  "toString",
  "valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i<l; i++) {
  if map.hasOwnProperty(a[i])) {
    alert(a[i]);
  }
}

La buena noticia es que ECMAScript 5 define la función Object.keys(myObject), que devuelve las claves de un objeto como matriz y algunos navegadores (por ejemplo, Safari 4) ya la implementan.

 49
Author: Fabian Jakobs,
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-08-31 16:31:43

En los navegadores modernos (ECMAScript 5) para obtener todas las propiedades enumerables puede hacer:

Objeto.keys (obj) (Compruebe el enlace para obtener un fragmento de código para la compatibilidad con versiones anteriores en los navegadores más antiguos)

O para obtener también propiedades no enumerables:

Objeto.getOwnPropertyNames (obj)

Compruebe la tabla de compatibilidad de ECMAScript 5

Información Adicional: ¿Qué es un atributo enumerable?

 40
Author: Carlos Ruana,
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-11-07 11:54:39

Creo que un ejemplo del caso que me ha cogido por sorpresa es relevante:

var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
  document.writeln( propertyName + " : " + myObject[propertyName] );
}

Pero para mi sorpresa, la salida es

name : Cody
status : Surprised
forEach : function (obj, callback) {
    for (prop in obj) {
        if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
            callback(prop);
        }
    }
}

¿Por qué? Otro script en la página ha extendido el prototipo de objeto:

Object.prototype.forEach = function (obj, callback) {
  for ( prop in obj ) {
    if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
      callback( prop );
    }
  }
};
 22
Author: cyberhobo,
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-12-02 19:35:04
for (prop in obj) {
    alert(prop + ' = ' + obj[prop]);
}
 14
Author: Andrew Hedges,
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
2008-09-17 22:51:50

Código JavaScript simple:

for(var propertyName in myObject) {
   // propertyName is what you want.
   // You can get the value like this: myObject[propertyName]
}
[2]} jQuery:
jQuery.each(obj, function(key, value) {
   // key is what you want.
   // The value is in: value
});
 10
Author: EmRa228,
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-06-01 22:51:25

Lo encontré... for (property in object) { // do stuff } listará todas las propiedades, y por lo tanto todas las variables declaradas globalmente en el objeto window..

 9
Author: davenpcj,
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-05-15 14:36:27

Si está utilizando el subrayado .biblioteca js, puede usar las teclas function :

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]
 8
Author: dkl,
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-06-01 22:51:53

He aquí cómo enumerar las propiedades de un objeto:

var params = { name: 'myname', age: 'myage' }

for (var key in params) {
  alert(key + "=" + params[key]);
}
 8
Author: Chtiwi Malek,
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-06-01 22:52:14

El dict de Python tiene el método 'keys', y eso es realmente útil. Creo que en JavaScript podemos tener algo así:

function keys(){
    var k = [];
    for(var p in this) {
        if(this.hasOwnProperty(p))
            k.push(p);
    }
    return k;
}
Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false });

EDITAR: Pero la respuesta de @ carlos-ruana funciona muy bien. Probé el Objeto.teclas (ventana), y el resultado es lo que esperaba.

EDITAR después de 5 años: no es buena idea extender Object, porque puede entrar en conflicto con otras bibliotecas que quieran usar keys en sus objetos y conducirá a un comportamiento impredecible en su proyecto. @carlos-ruana la respuesta es la forma correcta de obtener las claves de un objeto.

 6
Author: Fabio Montefuscolo,
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-07 16:40:38

Puede usar el for de bucle.

Si quieres un array usa:

Object.keys(object1)

Ref. Objeto.llaves()

 1
Author: Walle Cyril,
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-08-25 12:03:24

Si está tratando de enumerar las propiedades para escribir código nuevo contra el objeto, le recomendaría usar un depurador como Firebug para verlas visualmente.

Otra técnica útil es utilizar el Objeto del Prototipo.toJSON () para serializar el objeto a JSON, que le mostrará tanto los nombres de propiedad como los valores.

var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']};
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}'

Http://www.prototypejs.org/api/object/tojson

 0
Author: Chase Seibert,
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
2008-09-17 19:45:42

Todavía soy un principiante en JavaScript, pero escribí una pequeña función para imprimir recursivamente todas las propiedades de un objeto y sus hijos:

getDescription(object, tabs) {
  var str = "{\n";
  for (var x in object) {
      str += Array(tabs + 2).join("\t") + x + ": ";
      if (typeof object[x] === 'object' && object[x]) {
        str += this.getDescription(object[x], tabs + 1);
      } else {
        str += object[x];
      }
      str += "\n";
  }
  str += Array(tabs + 1).join("\t") + "}";
  return str;
}
 0
Author: Felix Lapalme,
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-12-02 19:35:56