Obtenir un tableau de clés d'objet

372

Je voudrais obtenir les clés d'un objet JavaScript sous forme de tableau, soit en jQuery soit en JavaScript pur.

Y a-t-il une manière moins verbeuse que cela?

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}
Richard
la source
4
Outre l'ajout if(foo.hasOwnProperty(key)), c'est ce que je ferais. Ou, utilisez $.map.
Rocket Hazmat
10
Oh pour un one-liner Pythonic, cependant ...
Richard
une vieille question qui ne vaut donc pas une réponse complète, mais pour ceux qui veulent tripoter ... jsfiddle.net/LR5D9/3 cette solution traite du problème des déclarations de prototype qui gâchent les for var in xboucles
non synchronisé

Réponses:

619

Utilisation Object.keys:

var foo = {
  'alpha': 'puffin',
  'beta': 'beagle'
};

var keys = Object.keys(foo);
console.log(keys) // ['alpha', 'beta'] 
// (or maybe some other order, keys are unordered).

Il s'agit d'une fonctionnalité ES5. Cela signifie que cela fonctionne dans tous les navigateurs modernes, mais ne fonctionnera pas dans les navigateurs hérités .

La cale ES5 a une implémentation de Object.keysvous pouvez voler

Raynos
la source
5
Remarque: cela ne fonctionne que sur les navigateurs modernes (j'entends par là pas IE <9).
Rocket Hazmat
2
Et qu'en est-il des navigateurs mobiles?
Marwen Trabelsi
1
@SmartyTwiti: Je ne suis pas sûr. Je suppose que c'est le cas dans Chrome ou Firefox.
Rocket Hazmat
MDN a également le Polyfill mentionné ci-dessus, mais note des bogues dans IE7 et peut-être 8, puis se réfère à un Polyfill beaucoup plus court ici: tokenposts.blogspot.com.au/2012/04/…
Campbeln
Alors, comment faisait-on avant ES5?
Andrew S
59

Vous pouvez utiliser jQuery $.map.

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
  return i;
});
Rocket Hazmat
la source
Ou each, si vous faites quelque chose avec eux. $.each(foo, function(index, value){/* do something with index */});
Chris
33

Bien sûr, Object.keys()c'est le meilleur moyen d'obtenir les clés d'un objet. S'il n'est pas disponible dans votre environnement, il peut être simplifié à l' aide de code comme dans votre exemple (sauf que vous devrez prendre en compte que votre boucle itérera sur toutes les propriétés de la chaîne de prototype, contrairement Object.keys()au comportement de).

Cependant, votre exemple de code ...

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}

jsFiddle .

... pourrait être modifié. Vous pouvez effectuer l'affectation directement dans la partie variable .

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [], i = 0;
for (keys[i++] in foo) {}

jsFiddle .

Bien sûr, ce comportement est différent de ce qui Object.keys()se passe réellement ( jsFiddle ). Vous pouvez simplement utiliser le shim sur la documentation MDN .

alex
la source
8
J'ai aimé ce var keys = [], i = 0; for (keys[i++] in foo) {}+1
Jashwant
J'ai entendu dire que "for in" ne garantit pas l'ordre, savez-vous si Object.keys le fait?
Chris Stephens
@ChrisStephens Ni garantir l'ordre, même si les clés finissent par être dans un tableau ordonné.
alex
2
toutes ces solutions ont besoin d'un hasOwnProperty()contrôle, sûrement?
non synchronisé
1
@TIMINeutron Il n'y a aucune raison pour que ce ne soit pas le cas :)
alex
7

Je ne sais pas moins verbeux mais j'ai été inspiré pour contraindre ce qui suit sur une ligne par la demande à une ligne, je ne sais pas comment c'est Pythonic cependant;)

var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
Dexygen
la source
3
Peut-être que cela devrait être var enumerableKeysOnThePrototypeChain;)
alex
1
Peut-être que nous sommes assez intelligents pour savoir que nous n'avons pas à nous soucier de hasOwnProperty si l'objet est créé entièrement sous notre responsabilité au lieu d'être importé d'ailleurs
Dexygen
pas aussi pythonique que la deuxième réponse de @ alex ( for (keys[i++] in foo) {}), car vous êtes toujours en train de jouer Array.push()(sans parler de la déclaration d'une fonction entière). Une implémentation pythonique devrait s'appuyer autant sur la compréhension implicite que possible, et à défaut, en utilisant une expression lambda.
cowbert
4

Dans le cas où vous cherchez ici quelque chose pour répertorier les clés d'un objet imbriqué de profondeur n en tant que tableau plat:

const getObjectKeys = (obj, prefix = '') => {
  return Object.entries(obj).reduce((collector, [key, val]) => {
    const newKeys = [ ...collector, prefix ? `${prefix}.${key}` : key ]
    if (Object.prototype.toString.call(val) === '[object Object]') {
      const newPrefix = prefix ? `${prefix}.${key}` : key
      const otherKeys = getObjectKeys(val, newPrefix)
      return [ ...newKeys, ...otherKeys ]
    }
    return newKeys
  }, [])
}

console.log(getObjectKeys({a: 1, b: 2, c: { d: 3, e: { f: 4 }}}))

Cody Moniz
la source
1

Sommaire

Pour obtenir toutes les clés d'un objet que vous pouvez utiliser Object.keys(). Object.keys()prend un objet comme argument et retourne un tableau de toutes les clés.

Exemple:

const object = {
  a: 'string1',
  b: 42,
  c: 34
};

const keys = Object.keys(object)

console.log(keys);

console.log(keys.length) // we can easily access the total amount of properties the object has

Dans l'exemple ci-dessus, nous stockons un tableau de clés dans la clé const. Nous pouvons alors facilement accéder à la quantité de propriétés sur l'objet en vérifiant la longueur du tableau de clés.

Obtenir les valeurs avec: Object.values()

La fonction complémentaire de Object.keys()is Object.values(). Cette fonction prend un objet comme argument et renvoie un tableau de valeurs. Par exemple:

const object = {
  a: 'random',
  b: 22,
  c: true
};


console.log(Object.values(object));

Willem van der Veen
la source
1

Si vous décidez d'utiliser Underscore.js, vous feriez mieux de le faire

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
mohammad javad ahmadi
la source