web-dev-qa-db-fra.com

Comment énumérer les propriétés d'un objet JavaScript?

Comment énumérer les propriétés d'un objet JavaScript?

En fait, je souhaite répertorier toutes les variables définies et leurs valeurs, mais j'ai appris que la définition d'une variable crée en réalité une propriété de l'objet window.

647
davenpcj

Assez simple:

for(var propertyName in myObject) {
   // propertyName is what you want
   // you can get the value like this: myObject[propertyName]
}

Maintenant, vous n'obtiendrez pas les variables privées de cette façon car elles ne sont pas disponibles.


EDIT: @ bitwiseplatypus est correct, sauf si vous utilisez la méthode hasOwnProperty(), vous obtiendrez des propriétés héritées. Cependant, je ne sais pas pourquoi une personne familiarisée avec la programmation orientée objet s'attendrait rien de moins! En général, quelqu'un qui en parle a été soumis aux avertissements de Douglas Crockford à ce sujet, ce qui me confond encore un peu. Encore une fois, l'héritage fait partie des OO langages et fait donc partie de JavaScript, même s'il est prototypique.

Cela dit, hasOwnProperty() est utile pour filtrer, mais nous n’avons pas besoin de lancer un avertissement comme s'il y avait quelque chose de dangereux dans obtenir des propriétés héritées.

EDIT 2: @ bitwiseplatypus rappelle la situation qui pourrait se produire si quelqu'un ajoute des propriétés/méthodes à vos objets à un moment ultérieur à celui où vous avez écrit vos objets (via son prototype) - alors qu'il est Il est vrai que cela pourrait provoquer un comportement inattendu, personnellement, je ne vois pas cela comme étant mon problème. Juste une question d'opinion. De plus, si je conçois les choses de manière à utiliser des prototypes lors de la construction de mes objets tout en ayant un code qui itère sur les propriétés de l'objet et que je souhaite utiliser toutes les propriétés héritées? Je n'utiliserais pas hasOwnProperty(). Ensuite, supposons que quelqu'un ajoute de nouvelles propriétés plus tard. Est-ce ma faute si les choses se comportent mal à ce moment-là? Je ne pense pas. Je pense que c’est la raison pour laquelle jQuery, à titre d’exemple, a spécifié des moyens d’en étendre le fonctionnement (via jQuery.extend et jQuery.fn.extend).

809
Jason Bunting

Utilisez une boucle for..in pour énumérer les propriétés d'un objet, mais soyez prudent. L'énumération retournera des propriétés non seulement de l'objet en cours d'énumération, mais également des prototypes de tout objet parent.

var myObject = {foo: 'bar'};

for (var name in myObject) {
  alert(name);
}

// results in a single alert of 'foo'

Object.prototype.baz = 'quux';

for (var name in myObject) {
  alert(name);
}

// results in two alerts, one for 'foo' and one for 'baz'

Pour éviter d'inclure des propriétés héritées dans votre énumération, vérifiez hasOwnProperty():

for (var name in myObject) {
  if (myObject.hasOwnProperty(name)) {
    alert(name);
  }
}

Edit: Je ne suis pas d'accord avec la déclaration de JasonBunting selon laquelle nous n'avons pas à nous inquiéter de l'énumération des propriétés héritées. Il y a un danger en énumérant les propriétés héritées que vous n'attendiez pas, car cela pourrait modifier le comportement de votre code.

Peu importe que ce problème existe dans d'autres langues; En effet, JavaScript est particulièrement vulnérable, car les modifications apportées au prototype d'un objet affectent les objets enfants, même si la modification a lieu après l'instanciation.

C’est la raison pour laquelle JavaScript fournit hasOwnProperty(), et vous devez donc l’utiliser pour vous assurer que le code tiers (ou tout autre code pouvant modifier un prototype) ne rompt pas le vôtre. Mis à part l'ajout de quelques octets supplémentaires de code, l'utilisation de hasOwnProperty() ne présente aucun inconvénient.

218
Ryan Grove

La méthode standard, qui a déjà été proposée à plusieurs reprises, est la suivante:

for (var name in myObject) {
  alert(name);
}

Cependant, Internet Explorer 6, 7 et 8 ont un bogue dans l'interpréteur JavaScript, ce qui a pour effet que certaines clés ne sont pas énumérées. Si vous exécutez ce code:

var obj = { toString: 12};
for (var name in obj) {
  alert(name);
}

If alertera "12" dans tous les navigateurs sauf IE. IE ignorera tout simplement cette clé. Les valeurs de clé affectées sont:

  • isPrototypeOf
  • hasOwnProperty
  • toLocaleString
  • toString
  • valueOf

Pour être vraiment en sécurité dans IE, vous devez utiliser quelque chose comme:

for (var key in myObject) {
  alert(key);
}

var shadowedKeys = [
  "isPrototypeOf",
  "hasOwnProperty",
  "toLocaleString",
  "toString",
  "valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i<l; i++) {
  if map.hasOwnProperty(a[i])) {
    alert(a[i]);
  }
}

La bonne nouvelle est qu'EcmaScript 5 définit la fonction Object.keys(myObject), qui renvoie les clés d'un objet sous forme de tableau et que certains navigateurs (par exemple, Safari 4) l'implémentent déjà.

51
Fabian Jakobs

Dans les navigateurs modernes (ECMAScript 5) pour obtenir toutes les propriétés énumérables, vous pouvez effectuer:

Object.keys (obj) (Vérifiez le lien pour obtenir un extrait de code pour la compatibilité ascendante sur les anciens navigateurs)

Ou pour obtenir également des propriétés non énumérables:

Object.getOwnPropertyNames (obj)

Consultez le tableau de compatibilité ECMAScript 5

Informations supplémentaires: Qu'est-ce qu'un attribut énumérable?

44
Carlos Ruana

Je pense qu'un exemple du cas qui m'a pris par surprise est pertinent:

var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
  document.writeln( propertyName + " : " + myObject[propertyName] );
}

Mais à ma grande surprise, la sortie est

name : Cody
status : Surprised
forEach : function (obj, callback) {
    for (prop in obj) {
        if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
            callback(prop);
        }
    }
}

Pourquoi? Un autre script sur la page a étendu le prototype d'objet:

Object.prototype.forEach = function (obj, callback) {
  for ( prop in obj ) {
    if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
      callback( prop );
    }
  }
};
25
cyberhobo
for (prop in obj) {
    alert(prop + ' = ' + obj[prop]);
}
16
Andrew Hedges

Code JavaScript simple:

for(var propertyName in myObject) {
   // propertyName is what you want.
   // You can get the value like this: myObject[propertyName]
}

jQuery:

jQuery.each(obj, function(key, value) {
   // key is what you want.
   // The value is in: value
});
10
EmRa228

Je l'ai trouvé ... for (property in object) { // do stuff } listera toutes les propriétés, et donc toutes les variables déclarées globalement sur l'objet window.

9
davenpcj

Voici comment énumérer les propriétés d'un objet:

var params = { name: 'myname', age: 'myage' }

for (var key in params) {
  alert(key + "=" + params[key]);
}
8
Chtiwi Malek

Si vous utilisez la bibliothèque nderscore.js , vous pouvez utiliser la fonction keys :

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]
7
dkl

Vous pouvez utiliser la boucle for de.

Si vous voulez un tableau utilisez:

Object.keys(object1)

Réf. Object.keys ()

6
Walle Cyril

Le dict de Python a la méthode 'keys', et c'est vraiment utile. Je pense qu'en JavaScript on peut avoir quelque chose comme ça:

function keys(){
    var k = [];
    for(var p in this) {
        if(this.hasOwnProperty(p))
            k.Push(p);
    }
    return k;
}
Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false });

EDIT: Mais la réponse de @ carlos-ruana fonctionne très bien. J'ai testé Object.keys (fenêtre), et le résultat est ce que j'attendais.

EDIT après 5 ans: il n’est pas judicieux d’étendre Object, car cela peut entrer en conflit avec d’autres bibliothèques susceptibles d’utiliser keys sur leurs objets, ce qui entraînera un comportement imprévisible de votre projet. @ carlos-ruana answer est le moyen correct d'obtenir les clés d'un objet.

5
Fabio Montefuscolo

Si vous essayez d'énumérer les propriétés afin d'écrire du nouveau code par rapport à l'objet, je vous recommanderais d'utiliser un débogueur comme Firebug pour les voir visuellement.

Une autre technique pratique consiste à utiliser Object.toJSON () de Prototype pour sérialiser l'objet en JSON, ce qui vous montrera les noms et les valeurs des propriétés.

var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']};
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}'

http://www.prototypejs.org/api/object/tojson

2
Chase Seibert

Je suis toujours un débutant en JavaScript, mais j'ai écrit une petite fonction pour imprimer de manière récursive toutes les propriétés d'un objet et de ses enfants:

getDescription(object, tabs) {
  var str = "{\n";
  for (var x in object) {
      str += Array(tabs + 2).join("\t") + x + ": ";
      if (typeof object[x] === 'object' && object[x]) {
        str += this.getDescription(object[x], tabs + 1);
      } else {
        str += object[x];
      }
      str += "\n";
  }
  str += Array(tabs + 1).join("\t") + "}";
  return str;
}
0
Felix Lapalme