Uzyskaj tablicę kluczy obiektu

371

Chciałbym uzyskać klucze obiektu JavaScript jako tablicę w jQuery lub czystym JavaScript.

Czy istnieje mniej szczegółowy sposób niż ten?

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}
Richard
źródło
4
Poza dodaniem if(foo.hasOwnProperty(key)), to właśnie zrobiłbym. Lub użyj $.map.
Rocket Hazmat
10
Och, jak na jedno-linijkę w języku Python ...
Richard
stare pytanie, więc nie warta pełnej odpowiedzi, ale dla tych, którzy chcą się bawić ... jsfiddle.net/LR5D9/3 to rozwiązanie dotyczy problemu deklaracji prototypowych zepsutychfor var in x pętli
niezsynchronizowany

Odpowiedzi:

618

Użyj 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).

To jest funkcja ES5. Oznacza to, że działa we wszystkich nowoczesnych przeglądarkach, ale nie będzie działać w starszych przeglądarkach .

Podkładka ES5 ma implementację, Object.keysktórą możesz ukraść

Raynos
źródło
5
Uwaga: Działa to tylko w nowoczesnych przeglądarkach (to znaczy nie IE <9).
Rocket Hazmat
2
A co z przeglądarkami mobilnymi?
Marwen Trabelsi
1
@SmartyTwiti: Nie jestem pewien. Zakładam, że działa tak jak Chrome lub Firefox.
Rocket Hazmat
MDN ma również wspomniany wyżej Polyfill, ale odnotowuje błędy w IE7 i może 8, a następnie odnosi się do znacznie krótszego Polyfill tutaj: tokenposts.blogspot.com.au/2012/04/…
Campbeln
Jak to zrobić przed ES5?
Andrew S
59

Możesz użyć jQuery's $.map.

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
  return i;
});
Rakieta Hazmat
źródło
Lub each, jeśli coś z nimi robisz. $.each(foo, function(index, value){/* do something with index */});
Chris
33

Oczywiście Object.keys()jest to najlepszy sposób na zdobycie kluczy do obiektu. Jeśli nie jest dostępny w twoim środowisku, można go trywialnie pomijać za pomocą kodu, takiego jak w twoim przykładzie (z wyjątkiem tego, że musisz wziąć pod uwagę, że twoja pętla będzie iterować wszystkie właściwości w łańcuchu prototypowym, w przeciwieństwie do Object.keys()zachowania).

Twój przykładowy kod ...

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

jsFiddle .

... można zmodyfikować. Możesz wykonać przypisanie bezpośrednio w części zmiennej .

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

jsFiddle .

Oczywiście takie zachowanie jest inne niż w Object.keys()rzeczywistości ( jsFiddle ). Możesz po prostu użyć podkładki dystansowej w dokumentacji MDN .

alex
źródło
8
Podobało mi się to var keys = [], i = 0; for (keys[i++] in foo) {}+1
Jashwant
Słyszałem, że „for in” nie gwarantuje kolejności, czy wiesz, czy obiekt Object.keys?
Chris Stephens
@ChrisStephens Żaden z nich nie gwarantuje kolejności, nawet jeśli klucze znajdą się w uporządkowanej tablicy.
alex
2
wszystkie te rozwiązania z hasOwnProperty()pewnością wymagają sprawdzenia?
niezsynchronizowany
1
@TIMINeutron Nie ma powodu, dla którego nie powinien :)
alex
7

Nie wiem o mniej gadatliwym, ale zainspirowało mnie to, aby wymusić na jednym wierszu prośbę o jeden wiersz, nie wiem jednak, jak to jest w Pythonie;)

var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
Dexygen
źródło
3
Może to powinno być var enumerableKeysOnThePrototypeChain;)
Alex
1
Może jesteśmy na tyle sprytni, aby wiedzieć, że nie musimy się martwić hasOwnProperty, jeśli obiekt jest tworzony całkowicie pod naszym nadzorem, a nie importowany gdzie indziej
Dexygen
jednak nie tak pythoniczny jak druga odpowiedź @ Alexa ( for (keys[i++] in foo) {}), ponieważ nadal działasz Array.push()(nie wspominając o deklaracji całej funkcji). Implementacja w języku pythonowym powinna polegać w możliwie największym stopniu na zrozumieniu niejawnym, a jeśli to niemożliwe, za pomocą wyrażenia lambda.
cowbert
4

Jeśli szukasz tutaj czegoś, co wymienia klucze zagnieżdżonego obiektu o głębokości n jako płaskiej tablicy:

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
źródło
1

Podsumowanie

Aby uzyskać wszystkie klucze obiektu, którego możesz użyć Object.keys(). Object.keys()przyjmuje obiekt jako argument i zwraca tablicę wszystkich kluczy.

Przykład:

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

W powyższym przykładzie przechowujemy tablicę kluczy w kluczach const. Następnie możemy łatwo uzyskać dostęp do ilości właściwości obiektu, sprawdzając długość tablicy kluczy.

Uzyskanie wartości dzięki: Object.values()

Uzupełniającą funkcją Object.keys()jest Object.values(). Ta funkcja przyjmuje obiekt jako argument i zwraca tablicę wartości. Na przykład:

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


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

Willem van der Veen
źródło
1

Jeśli zdecydujesz się użyć Underscore.js, lepiej

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
mohammad javad ahmadi
źródło