Come posso accedere alle proprietà di un oggetto JavaScript se non conosco i nomi?


124

Supponi di avere un oggetto JavaScript come questo:

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

È possibile accedere alle proprietà tramite il nome della proprietà:

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

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

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

Il mio pensiero su come farlo finora è quello di passare i nomi delle proprietà alla funzione insieme ai dati, ma questo sembra un hack. Preferirei farlo con introspezione, se possibile.

Risposte:


144

Puoi scorrere i tasti in questo modo:

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

Questo registra "Nome" e "Valore".

Se hai un tipo di oggetto più complesso (non solo un semplice oggetto simile a un hash, come nella domanda originale), ti consigliamo di scorrere solo le chiavi che appartengono all'oggetto stesso, al contrario delle chiavi sul prototipo dell'oggetto :

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

Come hai notato, non è garantito che le chiavi siano in un ordine particolare. Nota come questo differisce da quanto segue:

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

Questo esempio scorre ciclicamente i valori, quindi registra Property Namee 0. NB: Ilfor each sintassi è supportata principalmente da Firefox, ma non da altri browser.

Se i tuoi browser di destinazione supportano ES5 o il tuo sito include es5-shim.js(consigliato), puoi anche utilizzare Object.keys:

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

e loop con Array.prototype.forEach:

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

L'hai appena inventato e te ne sei davvero liberato? Ben fatto ... =)
nichel-

Questo esiste in Firefox ( documenti ), ma il punto giusto non è universale. Aggiornerò la risposta per menzionarlo.
Ron DeVera,

28
btw alert è un brutto modo per eseguire il debug delle cose, prova console.log
StackOverflow

Questa è stata la risposta migliore quando è stata posta la domanda, ma sto rimuovendo il segno di spunta perché le versioni successive di JS hanno fornito strumenti migliori.
Adam Lassek,

65

Le vecchie versioni di JavaScript (<ES5) richiedono l'uso di un for..inciclo:

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

ES5 introduce Object.keys e Array # forEach che lo rendono un po 'più semplice:

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

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

1
Ora questo in realtà risponde alla domanda, ben fatto @Adam Lassek, molto ben fatto.
nichel-

È fuorviante usare sia "nome" che "valore" come chiavi dell'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']
James Nicholson

2
@JamesNicholson Sono d'accordo, modificato per essere meno confuso.
Adam Lassek,


4

Spesso vorrai esaminare le proprietà particolari 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(', ');
}

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

Ciò otterrà tutte le proprietà e i loro valori (ereditati o propri, enumerabili o meno) in un nuovo oggetto. l'oggetto originale non è stato toccato. Ora è possibile attraversare un nuovo oggetto usando

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

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
}

dove questa risposta fornisce ciò che è richiesto dall'OP ma una breve descrizione di ciò che si sta facendo e perché l'OP dovrebbe usarlo sarebbe utile, inoltre non dimenticare .hasOwnProperty()quando si utilizza per in per iterare un oggetto.
Muhammad Omer Aslam,

Grazie, sono d'accordo che .hasOwnProperty () itera l'oggetto ma itera per verificare una condizione, tuttavia usandola non possiamo stampare tutte le proprietà di un oggetto. Correggimi se sbaglio.
Mayank_VK,

Il hasOwnProperty()metodo restituisce booleanun'indicazione se l'oggetto ha la proprietà specificata come propria proprietà (anziché ereditarla) . vedi questo esempio
Muhammad Omer Aslam,

1

Puoi usare Object.keys () , "che restituisce una matrice di nomi di proprietà enumerabili propri di un determinato oggetto, nello stesso ordine che otteniamo con un normale ciclo."

Puoi usare qualsiasi oggetto al posto di 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]);
}


Potresti aggiungere ulteriori spiegazioni?
Keith Pinson,

Object.keys( stats )[key]non ha senso, lo sarà sempre 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

Ciò non aggiunge nulla alla risposta accettata e presenta le informazioni nel modo meno utile possibile. E non tiene conto delle proprietà ereditate.
Adam Lassek,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.