Pregunta ¿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?

De hecho, quiero enumerar todas las variables definidas y sus valores, pero aprendí que la definición de una variable realmente crea una propiedad del objeto ventana.


577
2017-09-17 18:10


origen


Respuestas:


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


EDITAR: @bitwiseplatypus es correcto que a menos que use el hasOwnProperty() método, obtendrá propiedades que son heredadas; sin embargo, no sé por qué alguien familiarizado con la programación orientada a objetos esperaría algo menos. Normalmente, alguien que plantea esto ha sido objeto de las advertencias de Douglas Crockford sobre esto, que todavía me confunden un poco. 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, eso dijo, hasOwnProperty()  es útil para filtrar, pero no es necesario que hagamos una advertencia como si hubiera algo peligroso en obtener propiedades heredadas.

EDICION 2: @bitwiseplatypus saca a colación 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 hago T ver eso como mi problema por completo. Solo una cuestión de opinión. Además, ¿qué pasa si diseño las cosas de tal manera que utilizo prototipos durante la construcción de mis objetos y aún tengo un código que itera sobre las propiedades del objeto y quiero todas las propiedades heredadas? No usaría hasOwnProperty(). Entonces, digamos, alguien agrega nuevas propiedades más tarde. ¿Es culpa mía 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 cómo funciona (a través de jQuery.extend y jQuery.fn.extend)


737
2017-09-17 18:12



Usar una for..in loop para enumerar las propiedades de un objeto, pero tenga cuidado. La enumeración devolverá propiedades no solo 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 Jason Bunting de que no tenemos que preocuparnos por enumerar las propiedades heredadas. Ahí es peligro al enumerar propiedades heredadas que no está esperando, 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 esta es la razón por la que debe usarlo para asegurarse de que el código de un tercero (o cualquier otro código que pueda modificar un prototipo) no rompa el suyo. Además de agregar algunos bytes adicionales de código, no hay inconveniente en usar hasOwnProperty().


211
2017-09-17 18:47



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 están enumeradas. 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, debes 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 matriz y algunos navegadores (por ejemplo, Safari 4) ya lo implementan.


48
2018-01-19 18:47



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

Object.keys (obj) (Consulte el enlace para obtener un fragmento de compatibilidad con versiones anteriores en navegadores antiguos)

O para obtener también propiedades no enumerables:

Object.getOwnPropertyNames (obj)

Comprobar la tabla de compatibilidad de ECMAScript 5

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


40
2017-11-07 11:54



Creo que un ejemplo del caso que me ha pillado 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 ampliado 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
2018-04-08 21:13



for (prop in obj) {
    alert(prop + ' = ' + obj[prop]);
}

13
2017-09-17 22:51



Código JavaScript simple:

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

10
2017-07-04 13:41



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


9
2017-09-17 18:13



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

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

8
2018-04-20 13:14



A continuación, le mostramos cómo enumerar las propiedades de un objeto:

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

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

8
2017-07-11 10:28



El dict de Python tiene el método de "claves", 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é Object.keys (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á un comportamiento impredecible en su proyecto. La respuesta @ carlos-ruana es la forma correcta de obtener las llaves de un objeto.


6
2017-11-13 14:52