Comment accéder aux propriétés d'un objet javascript si je ne connais pas les noms?

124

Disons que vous avez un objet javascript comme celui-ci:

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

Vous pouvez accéder aux propriétés par le nom de la propriété:

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

Mais est-il possible d'obtenir ces valeurs si vous ne connaissez pas le nom des propriétés? Le caractère non ordonné de ces propriétés rend-il impossible de les distinguer?

Dans mon cas, je pense spécifiquement à une situation où une fonction doit accepter une série de paires nom-valeur, mais les noms des propriétés peuvent changer.

Jusqu'à présent, je pense que je dois transmettre les noms des propriétés à la fonction avec les données, mais cela ressemble à un piratage. Je préférerais faire cela avec introspection si possible.

Adam Lassek
la source

Réponses:

144

Vous pouvez parcourir les touches comme ceci:

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

Cela enregistre "Nom" et "Valeur".

Si vous avez un type d'objet plus complexe (pas seulement un simple objet de type hachage, comme dans la question d'origine), vous voudrez uniquement parcourir les clés qui appartiennent à l'objet lui-même, par opposition aux clés sur le prototype de l'objet :

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

Comme vous l'avez noté, il n'est pas garanti que les clés soient dans un ordre particulier. Notez en quoi cela diffère de ce qui suit:

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

Cet exemple parcourt les valeurs en boucle, il consignera donc Property Nameet 0. NB: La for eachsyntaxe n'est généralement prise en charge que dans Firefox, mais pas dans les autres navigateurs.

Si vos navigateurs cibles prennent en charge ES5 ou si votre site inclut es5-shim.js(recommandé), vous pouvez également utiliser Object.keys:

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

et boucle avec Array.prototype.forEach:

Object.keys(data).forEach(function (key) {
  console.log(data[key]);
});
// => Logs "Property Name", 0
Ron DeVera
la source
Est-ce que vous venez de créer ce dernier et vous en êtes vraiment sorti? Bravo ... =)
nickl-
Cela existe dans Firefox ( docs ), mais il est juste que ce ne soit pas universel. Je mettrai à jour la réponse pour le mentionner.
Ron DeVera
28
L'alerte btw est un mauvais moyen de déboguer les choses, essayez console.log
StackOverflowed
C'était la meilleure réponse lorsque la question a été posée, mais je supprime la coche car les versions ultérieures de JS ont fourni de meilleurs outils.
Adam Lassek
65

Les anciennes versions de JavaScript (<ES5) nécessitent l'utilisation d'une for..inboucle:

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

ES5 introduit Object.keys et Array # forEach, ce qui facilite un peu la tâche:

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 présente Object.valueset Object.entries.

Object.values(data) // ['bar', 'quux']
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']]
Adam Lassek
la source
1
Maintenant, cela répond réellement à la question, bravo @Adam Lassek, très bien fait.
nickl-
Il est trompeur d'utiliser à la fois «nom» et «valeur» comme clés d'objet. Cette fonction ne renvoie que les clés d'une liste, pas les valeurs. {name1: 'value1', name2: 'value2'} évitera toute confusion pour les débutants. Object.keys (données); // ['name1', 'name2']
James Nicholson
2
@JamesNicholson Je suis d'accord, édité pour être moins déroutant.
Adam Lassek
10
for(var property in data) {
    alert(property);
}
karim79
la source
4

Vous voudrez souvent examiner les propriétés particulières d'une instance d'un objet, sans toutes ses méthodes et propriétés de prototype partagées:

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

Cela obtiendra toutes les propriétés et leurs valeurs (héritées ou propres, énumérables ou non) dans un nouvel objet. l'objet original est intact. Maintenant, un nouvel objet peut être parcouru en utilisant

var obj = { 'b': '4' }; //example object
var detailedObject = getDetailedObject(obj);
for(var o in detailedObject) {
    console.log('key: ' + o + '   value: ' + detailedObject[o]);
}
Shishir Arora
la source
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
la source
où cette réponse fournit ce qui est requis par l'OP mais une petite description de ce que vous faites et pourquoi l'OP devrait l'utiliser serait bien, n'oubliez pas non plus .hasOwnProperty()lorsque vous utilisez for in pour itérer un objet.
Muhammad Omer Aslam
Merci, je suis d'accord que .hasOwnProperty () itère l'objet mais il itère pour vérifier une condition, mais en l'utilisant, nous ne pouvons pas imprimer toutes les propriétés d'un objet. Corrigez-moi si je me trompe.
Mayank_VK
La hasOwnProperty()méthode renvoie un booleanindiquant si l'objet a la propriété spécifiée comme sa propre propriété (par opposition à l'hériter) . voir cet exemple
Muhammad Omer Aslam
1

Vous pouvez utiliser Object.keys () , "qui retourne un tableau des propres noms de propriétés énumérables d'un objet donné, dans le même ordre que nous obtenons avec une boucle normale."

Vous pouvez utiliser n'importe quel objet à la place 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
la source
Pouvez-vous ajouter plus d'explications?
Keith Pinson
Object.keys( stats )[key]n'a aucun sens, le sera toujours 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
la source
Cela n'ajoute rien à la réponse acceptée et présente les informations de la manière la moins utile possible. Et cela ne tient pas compte des propriétés héritées.
Adam Lassek