Pregunta

Esta pregunta ya tiene respuesta aquí:

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

De hecho, quiero enumerar todas las variables definidas y sus valores, pero aprendí que definir una variable en realidad crea una propiedad del objeto de ventana.

¿Fue útil?

Solución

Suficientemente simple:

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

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


EDITAR: @bitwiseplatypus es correcto que a menos que uses el hasOwnProperty() método, obtendrá propiedades que se heredan; sin embargo, no sé por qué alguien familiarizado con la programación orientada a objetos esperaría menos.Normalmente, alguien que menciona esto ha sido sometido a las advertencias de Douglas Crockford al respecto, lo que todavía me confunde un poco.Nuevamente, 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 bien, dicho esto, hasOwnProperty() es útil para filtrar, pero no necesitamos hacer sonar una advertencia como si hubiera algo peligroso en obtener propiedades heredadas.

EDITAR 2: @bitwiseplatypus plantea la situación que ocurriría si alguien agregara propiedades/métodos a sus objetos en un momento posterior al que escribió originalmente sus objetos (a través de su prototipo); si bien es cierto que esto podría causar un comportamiento inesperado, personalmente no lo hago. No veo eso como mi problema del todo.Sólo es una cuestión de opinión.Además, ¿qué pasa si diseño cosas de tal manera que uso prototipos durante la construcción de mis objetos y aún así tengo un código que itera sobre las propiedades del objeto y quiero que todas las propiedades sean heredadas?yo no usaría hasOwnProperty().Luego, digamos que alguien agrega nuevas propiedades más adelante.¿Es culpa mía si las cosas se portan mal en ese momento?No me parece.Creo que es por eso que jQuery, como ejemplo, ha especificado formas de ampliar su funcionamiento (a través de jQuery.extend y jQuery.fn.extend).

Otros consejos

Usar una for..in bucle para enumerar las propiedades de un objeto, pero tenga cuidado.La enumeración devolverá propiedades no sólo del objeto que se enumera, sino también de los prototipos de cualquier objeto principal.

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, verifique hasOwnProperty():

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

Editar: No estoy de acuerdo con la afirmación de JasonBunting de que no debemos preocuparnos por enumerar las propiedades heredadas.Allá es Es peligroso enumerar propiedades heredadas que no espera, porque puede cambiar el comportamiento de su código.

No importa si este problema existe en otros idiomas;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 creación de instancias.

Es por eso que JavaScript proporciona hasOwnProperty(), y es por eso que debes usarlo para asegurarte de que el código de terceros (o cualquier otro código que pueda modificar un prototipo) no rompa el tuyo.Aparte de agregar algunos bytes adicionales de código, no hay ningún inconveniente en usar hasOwnProperty().

La forma 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

Para estar 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 el Object.keys(myObject) función, que devuelve las claves de un objeto como una matriz y algunos navegadores (p. ej.Safari 4) ya lo implementa.

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

Objeto.claves(obj)(Consulte el enlace para obtener un fragmento de compatibilidad con versiones anteriores de navegadores más antiguos)

O para obtener también propiedades no enumerables:

Objeto.getOwnPropertyNames(obj)

Consulte la tabla de compatibilidad de ECMAScript 5

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

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

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

Pero para mi sorpresa, el resultado 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 ampliado el prototipo del Objeto:

Object.prototype.forEach = function (obj, callback) {
  for ( prop in obj ) {
    if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
      callback( prop );
    }
  }
};
for (prop in obj) {
    alert(prop + ' = ' + obj[prop]);
}

Código JavaScript sencillo:

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

jQuery:

jQuery.each(obj, function(key, value) {
   // key is what you want.
   // The value is in: value
});

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

A continuación se explica cómo enumerar las propiedades de un objeto:

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

for (var key in params) {
  alert(key + "=" + params[key]);
}

Si estás usando el Subrayado.js biblioteca, puedes usar la función llaves:

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]

Puedes usar el for de bucle.

Si quieres un uso de matriz:

Object.keys(object1)

Árbitro. Objeto.claves()

El dict de Python tiene un método de 'claves', y eso es realmente útil.Creo que en JavaScript podemos tener algo esto:

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é Object.keys (ventana) y el resultado es el 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 provocará un comportamiento impredecible en su proyecto.La respuesta de @ carlos-ruana es la forma correcta de obtener las claves de un objeto.

Si está intentando enumerar las propiedades para escribir código nuevo en el objeto, recomendaría usar un depurador como Firebug para verlos visualmente.

Otra técnica útil es utilizar Object.toJSON() de Prototype para serializar el objeto en JSON, lo que le mostrará tanto los nombres como los valores de las propiedades.

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

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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top