2009-03-23 5 views
109

Supposons que vous avez un objet javascript comme ceci:Comment puis-je accéder aux propriétés d'un objet javascript si je ne connais pas les noms?

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 la nom des propriétés? Est-ce que la nature désordonnée de ces propriétés rend impossible de les différencier?

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. Mes pensées sur la façon de faire cela jusqu'à présent est de passer les noms des propriétés à la fonction avec les données, mais cela ressemble à un hack. Je préférerais faire cela avec introspection si possible.

Répondre

46

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

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

ES5 présente Object.keys et Array#forEach ce qui en fait un peu plus 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 introduit Object.values et Object.entries.

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

Maintenant, cela répond effectivement à la question, bien fait @Adam Lassek, très bien fait. –

+0

Il est trompeur d'utiliser 'nom' et 'valeur' ​​comme clés d'objet. Cette fonction renvoie uniquement les clés d'une liste, pas les valeurs. {name1: 'value1', name2: 'value2'} évitera la confusion pour les débutants. Object.keys (données); // ['name1', 'name2'] –

+2

@JamesNicholson Je suis d'accord, édité pour être moins déroutant. –

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

Vous pouvez parcourir les clés comme celui-ci:

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

Cette consigne "Nom" et "Value". Si vous avez un type d'objet plus complexe (pas simplement un objet de type hachage simple, comme dans la question d'origine), vous souhaiterez uniquement faire défiler les clés qui appartiennent à l'objet lui-même, par opposition aux touches l'objet de prototype:

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

Comme vous l'avez dit, les clés ne sont pas garantis d'être dans un ordre particulier. Notez comment cela diffère de ce qui suit:

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

Cet exemple boucles à travers des valeurs, de sorte qu'il se connecter Property Name et 0. N.B .: La syntaxe for each est la plupart du temps supportée seulement dans Firefox, mais pas dans d'autres navigateurs.

Si vos navigateurs cibles prennent en charge ES5, ou votre site comprend 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 
+0

Avez-vous fait ce dernier et vous êtes-vous bien débrouillé? Bien joué ... =) –

+0

Cela existe dans Firefox ([docs] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for_each...in)), mais juste point que ce n'est pas universel. Je vais mettre à jour la réponse pour le mentionner. –

+25

btw alert est une mauvaise façon de déboguer les choses, essayez console.log – StackOverflowed

4

Vous souhaitez 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(', '); 
} 
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

Pourriez-vous ajouter plus d'explications? –

+0

'Object.keys (stats) [clé]' n'a aucun sens, sera toujours '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

Ceci n'ajoute rien à la réponse acceptée et présente l'information de la manière la moins utile possible. Et cela ne tient pas compte des propriétés héritées. –

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

Cela obtenir toutes les propriétés et leurs valeurs (héritée ou propre, dénombrable ou non) dans un nouvel objet. l'objet original est intact. Maintenant, un nouvel objet peut être traversé en utilisant

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