2009-03-23 10 views
109

Digamos que tienes un objeto JavaScript como esto:¿Cómo accedo a las propiedades de un objeto javascript si no conozco los nombres?

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

Respuesta

46

Las versiones antiguas de JavaScript (< ES5) requieren el uso de un bucle for..in:

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

ES5 introduce Object.keys y Array#forEach que hace esto 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 introduce Object.values y Object.entries.

Object.values(data) // ['bar', 'quux'] 
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']] 
+1

Ahora, esto realmente responde a la pregunta, bien hecho @ Adam Lassek, muy bien hecho. –

+0

Es engañoso usar tanto "nombre" como "valor" como claves de objeto. Esta función solo devuelve las claves en una lista, no los valores. {name1: 'value1', name2: 'value2'} evitará confusión para los principiantes. Object.keys (datos); // ['name1', 'name2'] –

+2

@JamesNicholson Estoy de acuerdo, editado para ser menos confuso. –

10
for(var property in data) { 
    alert(property); 
} 
127

Puede recorrer las llaves 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 tipo hash simple, como en la pregunta original), solo querrá recorrer las teclas que pertenecen al objeto en sí, a diferencia de las teclas prototype del objeto:

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

Como se anotó, las claves no se garantiza que sea en un orden particular. Tenga en cuenta cómo esto difiere de lo siguiente:

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

En este ejemplo se coloca a través de los valores, por lo que sería entrar Property Name y 0. N.B .: La sintaxis for each solo es soportada principalmente en Firefox, pero no en otros navegadores.

Si los navegadores de destino apoyan ES5, o su sitio incluye es5-shim.js (recomendado), también se puede utilizar Object.keys:

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

y el lazo con Array.prototype.forEach:

Object.keys(data).forEach(function (key) { 
    console.log(data[key]); 
}); 
// => Logs "Property Name", 0 
+0

¿Acabas de hacer esa última y realmente te saliste con la tuya? Bien hecho ... =) –

+0

Esto existe en Firefox ([documentos] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for_each...in)), pero punto justo que no es universal Actualizaré la respuesta para mencionar esto. –

+25

alerta btw es una forma incorrecta de depurar cosas, pruebe console.log – StackOverflowed

4

A menudo se deseará examine las propiedades particulares de una instancia de un objeto, sin todos sus métodos y propiedades 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(', '); 
} 
0
var fs = require("fs"); 

fs.stat(process.argv[1], function(err, stats){ 
if (err) { 
    console.log(err.message); 
    return;  
} else { 
console.log(JSON.stringify(stats)); 

/* this is the answer here */ 

    for (var key in Object.keys(stats)){ 
    var t = Object.keys(stats)[key]; 
    console.log(t + " value =: " + stats[t] ); 
    } 

/* to here, run in node */ 
    } 
}); 
+0

¿Podría agregar más explicaciones? –

+0

'Object.keys (stats) [key]' no tiene sentido, siempre será 'undefined'. –

-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 
+0

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

2
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 hará que todas las propiedades y sus valores (heredadas o propia, enumerable o no) en un nuevo objeto. el objeto original no ha sido tocado Ahora se puede atravesar un objeto nuevo usando

var obj = { 'b': '4' }; //example object 
var detailedObject = getDetailedObject(obj); 
for(var o in detailedObject) { 
    console.log('key: ' + o + ' value: ' + detailedObject[o]); 
} 
Cuestiones relacionadas