Ottieni array di chiavi dell'oggetto


372

Vorrei ottenere le chiavi di un oggetto JavaScript come un array, in jQuery o JavaScript puro.

C'è un modo meno dettagliato di questo?

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

4
Oltre ad aggiungere if(foo.hasOwnProperty(key)), è quello che farei. Oppure usa $.map.
Rocket Hazmat,

10
Oh per un one-liner Pythonic, però ...
Richard

una vecchia domanda quindi non merita una risposta completa, ma per coloro che vogliono giocherellare ... jsfiddle.net/LR5D9/3 questa soluzione affronta il problema delle dichiarazioni di prototipi che incasinano i for var in xcicli
non sincronizzati

Risposte:


619

Utilizzare 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).

Questa è una funzione ES5. Ciò significa che funziona in tutti i browser moderni ma non nei browser legacy .

Lo shim ES5 ha un'implementazione Object.keysche puoi rubare


5
Nota: questo funziona solo su browser moderni (non intendo IE <9).
Rocket Hazmat,

2
E i browser mobili?
Marwen Trabelsi,

1
@SmartyTwiti: non ne sono sicuro. Suppongo che lo faccia come in Chrome o Firefox.
Rocket Hazmat,

MDN ha anche il Polyfill sopra citato, ma rileva bug in IE7 e forse 8, quindi fa riferimento a un Polyfill molto più breve qui: tokenposts.blogspot.com.au/2012/04/…
Campbeln

Quindi come è stato fatto prima di ES5?
Andrew S,

59

Puoi usare jQuery $.map.

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
  return i;
});

Oppure each, se stai facendo qualcosa con loro. $.each(foo, function(index, value){/* do something with index */});
Chris

33

Naturalmente, Object.keys()è il modo migliore per ottenere le chiavi di un oggetto. Se non è disponibile nel tuo ambiente, può essere banalmente oscurato usando codice come nel tuo esempio (tranne che dovresti tener conto del fatto che il tuo ciclo eseguirà l'iterazione su tutte le proprietà nella catena del prototipo, a differenza Object.keys()del comportamento).

Tuttavia, il tuo codice di esempio ...

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

jsFiddle .

... potrebbe essere modificato. Puoi eseguire il compito direttamente nella parte variabile .

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

jsFiddle .

Naturalmente, questo comportamento è diverso da quello che Object.keys()effettivamente fa ( jsFiddle ). Si potrebbe semplicemente usare lo spessore sulla documentazione MDN .


8
Mi è piaciuto questo var keys = [], i = 0; for (keys[i++] in foo) {}+1
Jashwant il

Ho sentito che "for in" non garantisce l'ordine, sai se Object.keys lo fa?
Chris Stephens,

@ChrisStephens Né garantisce l'ordine, anche se le chiavi finiscono per essere in un array ordinato.
alex

2
tutte queste soluzioni hanno bisogno di un hasOwnProperty()controllo, sicuramente?
non sincronizzato il

1
@TIMINeutron Non c'è motivo per cui non dovrebbe :)
alex

7

Non so di meno prolisso, ma sono stato ispirato a forzare quanto segue su una riga dalla richiesta one-liner, non so come sia Pythonic;)

var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);

3
Forse dovrebbe essere var enumerableKeysOnThePrototypeChain;)
alex

1
Forse siamo abbastanza intelligenti da sapere che non dobbiamo preoccuparci di hasOwnProperty se l'oggetto viene creato interamente sotto la nostra sfera di competenza anziché essere importato da qualche altra parte
Dexygen

non altrettanto pitonico della seconda risposta di @ alex ( for (keys[i++] in foo) {}), perché stai ancora eseguendo Array.push()(per non parlare della dichiarazione di un'intera funzione). Un'implementazione pitonica dovrebbe basarsi il più possibile sulla comprensione implicita e, in mancanza, usando un'espressione lambda.
cowbert,

4

Nel caso in cui tu stia cercando qualcosa per elencare le chiavi di un oggetto nidificato n-depth come un array piatto:

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


1

Sommario

Per ottenere tutte le chiavi di un oggetto che puoi usare Object.keys(). Object.keys()accetta un oggetto come argomento e restituisce un array di tutte le chiavi.

Esempio:

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

Nell'esempio sopra memorizziamo un array di chiavi nella chiave const. Possiamo quindi accedere facilmente alla quantità di proprietà sull'oggetto controllando la lunghezza della matrice di chiavi.

Ottenere i valori con: Object.values()

La funzione complementare di Object.keys()è Object.values(). Questa funzione accetta un oggetto come argomento e restituisce una matrice di valori. Per esempio:

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


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


1

Se decidi di utilizzare Underscore.js è meglio farlo

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.