web-dev-qa-db-fra.com

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

Dites que je crée un objet ainsi:

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

Quel est le meilleur moyen de récupérer une liste des noms de propriété? c’est-à-dire que je voudrais finir avec des «clés» variables telles que

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

Dans les navigateurs modernes (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +), vous pouvez utiliser la méthode intégrée Object.keys :

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 par 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 recommanderais pas.

962
slashnick

Comme indiqué par slashnick , vous pouvez utiliser la construction "for in" pour parcourir un objet à l'aide de ses noms d'attribut. Cependant, vous parcourerez tous les noms d'attributs dans la chaîne de prototypes de l'objet. Si vous voulez parcourir uniquement sur les attributs propres à l'objet, vous pouvez utiliser la méthode Object # hasOwnProperty () . Donc avoir ce qui suit.

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

Comme Sam Dutton a répondu, une nouvelle méthode à cette fin a été introduite dans ECMAScript 5th Edition. Object.keys() fera ce que vous voulez et est pris en charge dans Firefox 4 , Chrome 6, Safari 5 et IE 9

Vous pouvez également très facilement implémenter la méthode dans les navigateurs qui ne la prennent pas en charge. Cependant, certaines des implémentations 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 hasOwnProperty () et renverra les propriétés héritées de la chaîne de prototypes. De plus, il ne prend pas en compte le fameux bogue DontEnum dans Internet Explorer où des propriétés non énumérables sur la chaîne de prototypes amènent les propriétés déclarées localement portant le même nom à hériter de leur attribut DontEnum.

L'implémentation de Object.keys () vous donnera une solution plus robuste.

EDIT: à la suite d’une récente discussion avec kangax , un contributeur connu de Prototype, j’ai implémenté la solution de contournement du bogue DontEnum basée sur le code de sa fonction Object.forIn() trouvée ici .

97
Andy E

Notez que Object.keys et d’autres méthodes ECMAScript 5 sont pris en charge par Firefox 4, Chrome 6, Safari 5, IE 9 et les versions ultérieures.

Par exemple: 

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

Tableau 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/

28
Sam Dutton

Object.getOwnPropertyNames(obj)

Cette fonction affiche également les propriétés non énumérables en plus de celles indiquées par Object.keys(obj).

Dans JS, chaque propriété a quelques propriétés, y compris un booléen enumerable.

En général, les propriétés non énumérables sont plus "internes" et moins souvent utilisées, mais il est intéressant de les examiner parfois pour voir ce qui se passe réellement.

Exemple:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})

console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

console.log(Object.keys(o))
// [ 'yes' ]

for (var x in o)
    console.log(x)
// yes, base

Notez également comment:

  • Object.getOwnPropertyNames et Object.keysnon remonter la chaîne du prototype pour trouver base
  • for in fait

Plus d'informations sur la chaîne de prototypes ici: https://stackoverflow.com/a/23877420/895245

Je suis un grand fan de la fonction de vidage.

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

16
Matt

Pourrait le faire avec jQuery comme suit:

var objectKeys = $.map(object, function(value, key) {
  return key;
});
14
sbonami

si vous essayez d’obtenir les éléments uniquement mais pas les fonctions, ce code peut vous aider.

this.getKeys = function() {

    var keys = new Array();
    for(var key in this) {

        if( typeof this[key] !== 'function') {

            keys.Push(key);
        }
    }
    return keys;
}

cela fait partie de mon implémentation de HashMap et je ne veux que les clés, "ceci" est l'objet hashmap qui contient les clés

9
zeacuss

Cela fonctionnera dans la plupart des navigateurs, même dans IE8, et aucune bibliothèque d'aucune sorte n'est requise. var i est votre clé.

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.Push(i); }
alert(keys);
8
qwerty_jones

Sous les navigateurs supportant js 1.8:

[i for(i in obj)]
7
Rix Beck

Mozilla a les détails complets de la mise en œuvre sur la façon de le faire dans un navigateur où ce n'est pas supporté, si cela peut vous aider:

if (!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 (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

      var result = [];

      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.Push(prop);
      }

      if (hasDontEnumBug) {
        for (var i=0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.Push(dontEnums[i]);
        }
      }
      return result;
    };
  })();
}

Vous pouvez l'inclure comme vous le souhaitez, mais éventuellement dans un fichier extensions.js en haut de votre pile de scripts.

6

Puisque j'utilise underscore.js dans presque tous les projets, j'utiliserais la fonction keys

var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));

La sortie de ce sera:

['name', 'hello']
4
schmijos

IE ne prend pas en charge (i in obj) les propriétés natives. Voici une liste de tous les accessoires que j'ai pu trouver.

Il semble que stackoverflow effectue un filtrage stupide.

La liste est disponible au bas de cet article de groupe Google: - https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0

4
Gareth Heyes

Construire sur la réponse acceptée. 

Si l'objet a des propriétés que vous souhaitez appeler, dites .properties () try!

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}
3
Sydwell

La solution fonctionne sur mes cas et mon navigateur:

var getKeys = function(obj) {
    var type = typeof  obj;
    var isObjectType = type === 'function' || type === 'object' || !!obj;

    // 1
    if(isObjectType) {
        return Object.keys(obj);
    }

    // 2
    var keys = [];
    for(var i in obj) {
        if(obj.hasOwnProperty(i)) {
            keys.Push(i)
        }
    }
    if(keys.length) {
        return keys;
    }

    // 3 - bug for ie9 <
    var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
    if(hasEnumbug) {
        var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
            'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];

        var nonEnumIdx = nonEnumerableProps.length;

        while (nonEnumIdx--) {
            var prop = nonEnumerableProps[nonEnumIdx];
            if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                keys.Push(prop);
            }
        }

    }

    return keys;
};
0
christian Nguyen

Utilisez Reflect.ownKeys()

var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]

Object.keys et Object.getOwnPropertyNames ne peuvent pas obtenir les propriétés non-enumerable . Cela fonctionne même pour les propriétés non-enumerable.

var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]
0
selmansamet