948 votes

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

Disons que je crée un objet ainsi :

var myObject =
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

Quelle est la meilleure façon de récupérer une liste de noms de propriétés ? Par exemple, j'aimerais obtenir des variables "clés" telles que.. :

keys == ["ircEvent", "method", "regex"]

3 votes

Un peu hors sujet, mais si vous utilisez underscore.js : _.keys(myJSONObject)

4 votes

TL;DR : Si vous voulez uniquement des propriétés énumérables : Object.keys(obj) Parfois, on veut aussi des propriétés non dénombrables. Assurez-vous de vous en souvenir si c'est le cas ! Pour les obtenir, utilisez Object.getOwnPropertyNames(obj) stackoverflow.com/a/32413145/1599699

1195voto

slashnick Points 9773

Dans les navigateurs modernes (IE9+, FF4+, Chrome5+, Opera12+, Safari5+), vous pouvez utiliser le module intégré Clé d'objet méthode :

var keys = Object.keys(myObject);

Ce qui précède a un polyfill complet mais une version simplifiée est :

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

Vous pouvez également remplacer var getKeys avec Object.prototype.keys pour vous permettre d'appeler .keys() sur n'importe quel objet. L'extension du prototype a des effets secondaires et je ne le recommande pas.

19 votes

Je mettrais à nouveau à jour le message suivant : "Vous pourriez être tenté de faire ceci au prototype d'objet... mais ne le faites pas !

5 votes

Si quelqu'un veut mettre la lumière, pourquoi n'est-il pas recommandé d'ajouter des fonctions au prototype d'un objet ?

2 votes

C'est une toute autre question, une recherche rapide ici sur stackoverflow ou sur google vous donnera beaucoup à lire.

270voto

Pablo Cabrera Points 3245

Comme slashnick a souligné, vous pouvez utiliser la construction "for in" pour itérer sur un objet pour ses noms d'attributs. Cependant, vous devrez itérer sur tous les noms d'attributs dans la chaîne de prototypes de l'objet. Si vous voulez itérer seulement sur les attributs propres de l'objet, vous pouvez utiliser la fonction Objet#hasOwnProperty() méthode. Il s'agit donc de ce qui suit.

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}

30 votes

J'aurais aimé lire ceci avant la réponse de Slashnic ci-dessus. J'ai dû passer 15 minutes à maintenir la touche esc car l'objet avait environ un million de propriétés, la plupart non utilisées, et j'avais une alerte sur lui.

1 votes

Voici un excellent article sur le sujet, écrit par Zakas lui-même : nczonline.net/blog/2010/07/27/

4 votes

LOL @MarkHenderson - mais la prochaine fois, il suffit de tuer le processus du navigateur et de le redémarrer au lieu de perdre 15 minutes :)

104voto

Andy E Points 132925

Comme l'a répondu Sam Dutton, une nouvelle méthode à cette fin a été introduite dans la 5e édition d'ECMAScript. Object.keys() fera ce que vous voulez et est soutenu dans Firefox 4 Chrome 6, Safari 5 et IE 9 .

Vous pouvez aussi très facilement mettre en œuvre cette méthode dans les navigateurs qui ne la prennent pas en charge. Cependant, certaines des implémentations existantes ne sont pas entièrement compatibles avec Internet Explorer. Voici une solution plus compatible :

Object.keys = Object.keys || (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
        DontEnums = [ 
            'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
            'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
        ],
        DontEnumsLength = DontEnums.length;

    return function (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");

        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }

        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }

        return result;
    };
})();

Notez que la réponse actuellement acceptée n'inclut pas de vérification de la présence de hasOwnProperty() et renverra les propriétés qui sont héritées par la chaîne de prototypes. Elle ne tient pas compte non plus du fameux bogue DontEnum d'Internet Explorer, qui fait que les propriétés non dénombrables de la chaîne de prototypes font que les propriétés déclarées localement et portant le même nom héritent de leur attribut DontEnum.

Mise en œuvre de Objet.keys() vous donnera une solution plus robuste.

EDITAR: suite à une discussion récente avec kangax un contributeur bien connu de Prototype, j'ai mis en œuvre la solution de contournement pour le bogue DontEnum en me basant sur le code de son fichier Object.forIn() fonction trouvée ici .

0 votes

Excellente réponse, je pense que la réponse acceptée reste la solution la plus performante et précise, en supposant qu'il s'agit toujours d'un dict JSON. C'est certainement celle à utiliser ailleurs.

1 votes

@David Caunt : Merci :-) Malheureusement, la réponse acceptée serait toujours victime du bogue DontEnum et on ne sait jamais quel objet JSON pourrait avoir une chaîne comme "valueOf" ou "constructor" comme l'une de ses clés. Il itérera également sur les extensions de Object.prototype . Il arrive souvent, cependant, qu'un code plus court soit beaucoup plus attrayant qu'un code plus gros et plus robuste, mais l'objectif de cette réponse est d'utiliser les fonctionnalités de l'ECMAScript 5. Object.keys() qui peut être implémenté dans les navigateurs qui ne le supportent pas en utilisant ce code. La version native serait encore plus performante que cela.

0 votes

Bon point - vous avez raison à propos du bug. J'espère que tout bon développeur testera les méthodes natives avant d'utiliser ses propres implémentations.

36voto

Sam Dutton Points 4638

Notez que Object.keys et les autres méthodes ECMAScript 5 sont prises en charge par Firefox 4, Chrome 6, Safari 5, IE 9 et plus.

Par exemple :

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

Table de compatibilité ECMAScript 5 : http://kangax.github.com/es5-compat-table/

Description des nouvelles méthodes : http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/

0 votes

Vérifiez également keys() dans la console pour Chrome Dev Tools, Firebug, etc.

0 votes

17voto

Matt Points 3858

Je suis un grand fan de la fonction de vidage.

http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion alt text

1 votes

+1 parce que je suis venu ici dans l'intention de construire quelque chose de similaire (bien que pas aussi bon).

1 votes

netgrow.com.au/assets/files/dump/dump.zip non trouvé Comment puis-je télécharger le dump javascript ?

0 votes

@Kiquenet chaque fois que j'ai voulu construire quelque chose comme ça, je me suis contenté de l'inspecteur d'objets ordinaire. Si vous voulez un rendu en HTML, il y a des choses telles que modules npm . Franchement, ce qui m'a bloqué, c'est que je voulais quelque chose de mieux que ce qu'il y a sur cette image mais je n'ai jamais réussi à le conceptualiser. C'est merdique de parcourir les objets dans l'inspecteur mais les heuristiques pour essayer de déduire le sens d'objets arbitraires (par exemple, trier des tableaux d'objets dans des tables avec des colonnes) ne fonctionnent pas toujours en pratique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X