Nesne anahtar dizisini alın


371

Bir JavaScript nesnesinin anahtarlarını bir dizi olarak jQuery veya saf JavaScript olarak almak istiyorum.

Bundan daha az ayrıntılı bir yol var mı?

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

4
Eklemenin yanı sıra, if(foo.hasOwnProperty(key))bunu yapardım. Veya kullanın $.map.
Roket Hazmat

10
Pythonic bir astar için olsa da ...
Richard

eski bir soru çok tam bir cevaba değmez, ama keman yapmak isteyenler için ... jsfiddle.net/LR5D9/3 Bu çözüm, for var in xdöngüleri karıştıran prototip bildirimleri sorunu ile ilgileniyor
senkronize olmayan

Yanıtlar:


618

Kullanım 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).

Bu bir ES5 özelliğidir. Bu, tüm modern tarayıcılarda çalıştığı, ancak eski tarayıcılarda çalışmadığı anlamına gelir .

ES5-shim'in çalabileceğiniz bir uygulaması varObject.keys


5
Not: Bu sadece modern tarayıcılarda çalışır (yani IE <9 değil).
Roket Hazmat

2
Peki ya mobil tarayıcılar?
Marwen Trabelsi

1
@SmartyTwiti: Emin değilim. Chrome veya Firefox gibi olduğunu varsayıyorum.
Rocket Hazmat

MDN ayrıca yukarıda belirtilen Polyfill'e sahiptir, ancak IE7 ve belki 8'deki hataları not eder, daha sonra burada çok daha kısa bir Polyfill'e atıfta bulunur: tokenposts.blogspot.com.au/2012/04/…
Campbeln

Peki bunu ES5'ten önce nasıl yaptı?
Andrew S

59

JQuery's kullanabilirsiniz $.map.

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

Ya eachda onlarla bir şeyler yapıyorsanız. $.each(foo, function(index, value){/* do something with index */});
Chris

33

Tabii ki, bir Nesnenin anahtarlarını almanın Object.keys()en iyi yolu. Ortamınızda yoksa , örneğinizdeki gibi kod kullanılarak önemsiz bir şekilde takılabilir (ancak, döngünüzün , Object.keys()davranışının aksine, prototip zincirindeki tüm özellikler üzerinde yineleneceğini dikkate almanız gerekir ).

Ancak, örnek kodunuz ...

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

jsFiddle .

... değiştirilebilir. Atamayı doğrudan değişken kısımda yapabilirsiniz.

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

jsFiddle .

Tabii ki, bu davranış Object.keys()gerçekte ne yaptığından farklıdır ( jsFiddle ). MDN belgelerindeki şimi kullanabilirsiniz .


8
Ben bunu beğendi var keys = [], i = 0; for (keys[i++] in foo) {}1
Jashwant

Ben "için in" sipariş garanti değil duydum, Object.keys biliyor musunuz?
Chris Stephens

@ChrisStephens Anahtarlar sıralı bir dizide olsa bile sıralamayı garanti etmez.
alex

2
tüm bu çözümlerin hasOwnProperty()mutlaka bir kontrole ihtiyacı var mı?
senkronize olmayan

1
@TIMINeutron Olmaması gereken hiçbir neden yok :)
alex

7

Daha az ayrıntılı bilmiyorum ama tek satırlık taleple aşağıdakileri bir satıra zorlamak için ilham aldım, ne kadar Pitonik olduğunu bilmiyorum;)

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

3
Belki de olmalı var enumerableKeysOnThePrototypeChain;)
alex

1
Belki de nesne tamamen başka bir yerden ithal edilmek yerine tamamen bizim görüşümüz altında yaratılırsa hasOwnProperty hakkında endişelenmemiz
gerekmediğini bilecek kadar zekiyiz

yine de @ alex'in 2. yanıtı ( for (keys[i++] in foo) {}) kadar pythonic değil , çünkü hala performans gösteriyorsunuz Array.push()(bütün bir işlevi bildirmekten bahsetmiyorum). Bir pitonik uygulama, mümkün olduğunca örtülü kavrayışa dayanmalı ve bunu başaramazsa, bir lambda ifadesi kullanmalıdır.
cowbert

4

Burada, n derinlikli iç içe bir nesnenin anahtarlarını düz bir dizi olarak listelemek için bir şey arıyorsanız:

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

özet

Bir Nesnenin tüm anahtarlarını almak için kullanabilirsiniz Object.keys(). Object.keys()bir nesneyi bağımsız değişken olarak alır ve tüm anahtarların bir dizisini döndürür.

Misal:

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

Yukarıdaki örnekte, const. Daha sonra, keys dizisinin uzunluğunu kontrol ederek nesne üzerindeki özellik miktarına kolayca erişebiliriz.

Değerlerin alınması: Object.values()

Tamamlayıcı fonksiyonu Object.keys()olan Object.values(). Bu işlev, bir nesneyi bağımsız değişken olarak alır ve bir değer dizisi döndürür. Örneğin:

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


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


1

Underscore.js kullanmaya karar verirseniz,

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.