¿Cómo accedo a las propiedades de un objeto javascript si no conozco los nombres?

124

Digamos que tiene un objeto javascript como este:

var data = { foo: 'bar', baz: 'quux' };

Puede acceder a las propiedades por el nombre de la propiedad:

var foo = data.foo;
var baz = data["baz"];

Pero, ¿es posible obtener estos valores si no conoce el nombre de las propiedades? ¿La naturaleza desordenada de estas propiedades hace que sea imposible distinguirlas?

En mi caso, estoy pensando específicamente en una situación en la que una función necesita aceptar una serie de pares de nombre-valor, pero los nombres de las propiedades pueden cambiar.

Mis pensamientos sobre cómo hacer esto hasta ahora es pasar los nombres de las propiedades a la función junto con los datos, pero esto se siente como un truco. Preferiría hacer esto con introspección si es posible.

Adam Lassek
fuente

Respuestas:

144

Puede recorrer las teclas de esta manera:

for (var key in data) {
  console.log(key);
}

Esto registra "Nombre" y "Valor".

Si tiene un tipo de objeto más complejo (no solo un objeto simple tipo hash, como en la pregunta original), solo querrá recorrer las teclas que pertenecen al objeto en sí, en lugar de las teclas del prototipo del objeto :

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    console.log(key);
  }
}

Como notó, no se garantiza que las claves estén en ningún orden en particular. Observe cómo esto difiere de lo siguiente:

for each (var value in data) {
  console.log(value);
}

Este ejemplo recorre los valores, por lo que registraría Property Namey 0. NB: la for eachsintaxis solo se admite principalmente en Firefox, pero no en otros navegadores.

Si sus navegadores de destino son compatibles con ES5, o si su sitio incluye es5-shim.js(recomendado), también puede usar Object.keys:

var data = { Name: 'Property Name', Value: '0' };
console.log(Object.keys(data)); // => ["Name", "Value"]

y bucle con Array.prototype.forEach:

Object.keys(data).forEach(function (key) {
  console.log(data[key]);
});
// => Logs "Property Name", 0
Ron DeVera
fuente
¿Acabas de inventar el último y realmente te saliste con la tuya? Bien hecho ... =)
nickl-
Esto existe en Firefox ( docs ), pero lo cierto es que no es universal. Actualizaré la respuesta para mencionar esto.
Ron DeVera
28
Por cierto, la alerta es una mala manera de depurar las cosas, prueba console.log
StackOverflowed
Esta fue la mejor respuesta cuando se hizo la pregunta, pero estoy eliminando la marca de verificación porque las versiones posteriores de JS han proporcionado mejores herramientas.
Adam Lassek
65

Las versiones anteriores de JavaScript (<ES5) requieren el uso de un for..inbucle:

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    // do something with key
  }
}

ES5 presenta Object.keys y Array # forEach, lo que lo hace un poco más fácil:

var data = { foo: 'bar', baz: 'quux' };

Object.keys(data); // ['foo', 'baz']
Object.keys(data).map(function(key){ return data[key] }) // ['bar', 'quux']
Object.keys(data).forEach(function (key) {
  // do something with data[key]
});

ES2017 presenta Object.valuesy Object.entries.

Object.values(data) // ['bar', 'quux']
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']]
Adam Lassek
fuente
1
Ahora esto realmente responde a la pregunta, bien hecho @Adam Lassek, muy bien hecho.
nickl-
Es engañoso usar tanto 'nombre' como 'valor' como claves de objeto. Esta función solo devuelve las teclas en una lista, no los valores. {name1: 'value1', name2: 'value2'} evitará confusión para los principiantes. Object.keys (datos); // ['nombre1', 'nombre2']
James Nicholson
2
@JamesNicholson Estoy de acuerdo, editado para ser menos confuso.
Adam Lassek
10
for(var property in data) {
    alert(property);
}
karim79
fuente
4

A menudo querrá examinar las propiedades particulares de una instancia de un objeto, sin todos sus métodos y propiedades de prototipo compartidos:

 Obj.prototype.toString= function(){
        var A= [];
        for(var p in this){
            if(this.hasOwnProperty(p)){
                A[A.length]= p+'='+this[p];
            }
        }

    return A.join(', ');
}
Kennebec
fuente
3
function getDetailedObject(inputObject) {
    var detailedObject = {}, properties;

    do {
        properties = Object.getOwnPropertyNames( inputObject );
        for (var o in properties) {
            detailedObject[properties[o]] = inputObject[properties[o]];
        }
    } while ( inputObject = Object.getPrototypeOf( inputObject ) );

    return detailedObject;
}

Esto obtendrá todas las propiedades y sus valores (heredados o propios, enumerables o no) en un nuevo objeto. El objeto original está intacto. Ahora se puede atravesar un nuevo objeto usando

var obj = { 'b': '4' }; //example object
var detailedObject = getDetailedObject(obj);
for(var o in detailedObject) {
    console.log('key: ' + o + '   value: ' + detailedObject[o]);
}
Shishir Arora
fuente
1
var obj = {
 a: [1, 3, 4],
 b: 2,
 c: ['hi', 'there']
 }
for(let r in obj){  //for in loop iterates all properties in an object
 console.log(r) ;  //print all properties in sequence
 console.log(obj[r]);//print all properties values
}
Mayank_VK
fuente
donde esta respuesta proporciona lo que requiere el OP pero una pequeña descripción de lo que está haciendo y por qué el OP debería usarlo sería bueno, tampoco se olvide .hasOwnProperty()cuando use for para iterar un objeto.
Muhammad Omer Aslam
Gracias, estoy de acuerdo en que .hasOwnProperty () itera el objeto pero itera para verificar una condición, sin embargo, al usarlo no podemos imprimir todas las propiedades de un objeto. Corrígeme si me equivoco.
Mayank_VK
El hasOwnProperty()método devuelve una booleanindicación de si el objeto tiene la propiedad especificada como su propia propiedad (en lugar de heredarla) . ver este ejemplo
Muhammad Omer Aslam el
1

Puede usar Object.keys () , "que devuelve una matriz de los nombres de propiedad enumerables de un objeto dado, en el mismo orden que obtenemos con un bucle normal".

Puede usar cualquier objeto en lugar de stats:

var stats = {
  a: 3,
  b: 6,
  d: 7,
  erijgolekngo: 35
}
/*  this is the answer here  */
for (var key in Object.keys(stats)) {
  var t = Object.keys(stats)[key];
  console.log(t + " value =: " + stats[t]);
}

Cloid J. Green
fuente
¿Podría agregar más explicaciones?
Keith Pinson el
Object.keys( stats )[key]no tiene sentido, siempre lo será undefined.
Adam Lassek
-2
var attr, object_information='';

for(attr in object){

      //Get names and values of propertys with style (name : value)
      object_information += attr + ' : ' + object[attr] + '\n'; 

   }


alert(object_information); //Show all Object
isaax2
fuente
Esto no agrega nada a la respuesta aceptada y presenta la información de la manera menos útil posible. Y no tiene en cuenta las propiedades heredadas.
Adam Lassek