2009-03-23 7 views
109

Diciamo che avete un oggetto JavaScript come questo:Come accedere alle proprietà di un oggetto javascript se non conosco i nomi?

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

È possibile accedere alle proprietà dal nome della proprietà:

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

Ma è possibile ottenere questi valori se non si conosce la nome delle proprietà? La natura non ordinata di queste proprietà rende impossibile distinguerle?

Nel mio caso, sto pensando specificamente a una situazione in cui una funzione deve accettare una serie di coppie nome-valore, ma i nomi delle proprietà potrebbero cambiare.

I miei pensieri su come fare questo finora è passare i nomi delle proprietà alla funzione insieme ai dati, ma questo sembra un hack. Preferirei farlo con l'introspezione, se possibile.

risposta

46

Le vecchie versioni di JavaScript (< ES5) richiedono l'utilizzo di un for..in ciclo:

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

ES5 introduce Object.keys e Array#forEach che rende questo un po 'più facile:

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 e Object.entries.

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

Ora questo in realtà risponde alla domanda, ben fatta @Adam Lassek, molto ben fatta. –

+0

È fuorviante usare sia 'nome' che 'valore' come chiavi oggetto. Questa funzione restituisce solo le chiavi in ​​un elenco, non i valori. {name1: 'value1', name2: 'value2'} eviterà confusione per i principianti. Object.keys (dati); // ['name1', 'name2'] –

+2

@JamesNicholson Sono d'accordo, modificato per essere meno confuso. –

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

È possibile scorrere le chiavi in ​​questo modo:

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

Questa registra "Nome" e "Valore".

Se si dispone di un tipo di oggetto più complesso (non solo un semplice oggetto di tipo hash, come nella domanda originale), si desidera solo eseguire il ciclo delle chiavi che appartengono all'oggetto stesso, al contrario dei tasti su del prototype oggetto:

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

Come annotato, chiavi non sono garantiti per essere in alcun ordine particolare. Si noti come questo si differenzia dalla seguente:

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

Questo esempio scorre valori, quindi sarebbe il login Property Name e 0. N.B .: La sintassi for each è principalmente supportata solo in Firefox, ma non in altri browser.

Se browser di destinazione supportano ES5, o il vostro sito contiene es5-shim.js (consigliato), è anche possibile utilizzare Object.keys:

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

e ciclo con Array.prototype.forEach:

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

Hai appena fatto l'ultimo e in realtà se l'è cavata? Ben fatto ... =) –

+0

Questo esiste in Firefox ([docs] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for_each...in)), ma il punto giusto che non è universale. Aggiornerò la risposta per menzionarlo. –

+25

btw alert è un brutto modo di eseguire il debug delle cose, prova console.log – StackOverflowed

4

Spesso si vuole esaminare le proprietà particolari di di un'istanza di un oggetto, senza tutti i suoi metodi e proprietà prototipo condivisi:

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

Potresti aggiungere ulteriori spiegazioni? –

+0

'Object.keys (stats) [key]' non ha senso, sarà sempre 'indefinito'. –

-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

Questo non aggiunge nulla alla risposta accettata e presenta le informazioni nel modo meno utile possibile. E non tiene conto delle proprietà ereditate. –

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

In questo modo ottenere tutte le proprietà ed i loro valori (ereditati o proprio, enumerabile o meno) in un nuovo oggetto. l'oggetto originale non è stato toccato. Ora il nuovo oggetto può essere attraversato usando

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