Dapatkan berbagai kunci objek

372

Saya ingin mendapatkan kunci dari objek JavaScript sebagai array, baik dalam jQuery atau JavaScript murni.

Apakah ada cara yang kurang bertele-tele dari ini?

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}
Richard
sumber
4
Selain menambahkan if(foo.hasOwnProperty(key)), itulah yang akan saya lakukan. Atau, gunakan $.map.
Rocket Hazmat
10
Oh untuk Pythonic one-liner, meskipun ...
Richard
sebuah pertanyaan lama sehingga tidak layak jawaban penuh, tetapi bagi mereka yang ingin mengutak-atik ... jsfiddle.net/LR5D9/3 solusi ini berkaitan dengan masalah deklarasi prototipe mengacaukan for var in xloop
tidak disinkronkan

Jawaban:

619

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

Ini adalah fitur ES5. Ini berarti ia berfungsi di semua browser modern tetapi tidak akan berfungsi di browser lawas .

ES5-shim memiliki implementasi Object.keysyang dapat Anda curi

Raynos
sumber
5
Catatan: Ini hanya berfungsi pada browser modern (maksud saya bukan IE <9).
Rocket Hazmat
2
Dan bagaimana dengan browser seluler?
Marwen Trabelsi
1
@SmartyTwiti: Saya tidak yakin. Saya akan menganggapnya seperti Chrome atau Firefox.
Rocket Hazmat
MDN juga memiliki Polyfill yang disebutkan di atas, tetapi mencatat bug di IE7 dan mungkin 8, kemudian merujuk ke Polyfill yang jauh lebih pendek di sini: tokenposts.blogspot.com.au/2012/04/…
Campbeln
Jadi bagaimana orang melakukan ini sebelum ES5?
Andrew S
59

Anda dapat menggunakan jQuery's $.map.

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
  return i;
});
Roket Hazmat
sumber
Atau each, jika Anda melakukan sesuatu dengan mereka. $.each(foo, function(index, value){/* do something with index */});
Chris
33

Tentu saja, Object.keys()adalah cara terbaik untuk mendapatkan kunci Object. Jika itu tidak tersedia di lingkungan Anda, itu dapat shimmed sepele menggunakan kode seperti dalam contoh Anda (kecuali Anda harus mempertimbangkan loop Anda akan beralih ke semua properti di rantai prototipe, tidak seperti Object.keys()perilaku).

Namun, kode contoh Anda ...

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

jsFiddle .

... dapat dimodifikasi. Anda dapat melakukan tugas tepat di bagian variabel .

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

jsFiddle .

Tentu saja, perilaku ini berbeda dengan apa yang Object.keys()sebenarnya dilakukan ( jsFiddle ). Anda cukup menggunakan shim pada dokumentasi MDN .

alex
sumber
8
Saya menyukai ini var keys = [], i = 0; for (keys[i++] in foo) {}+1
Jashwant
Saya mendengar bahwa "untuk masuk" tidak menjamin pesanan, apakah Anda tahu jika Object.keys melakukannya?
Chris Stephens
@ChrisStephens Tidak ada jaminan pesanan, bahkan jika kunci berakhir dalam array yang dipesan
alex
2
semua solusi ini perlu hasOwnProperty()diperiksa, tentunya?
tidak disinkronkan
1
@TIMINeutron Tidak ada alasan mengapa tidak boleh :)
alex
7

Saya tidak tahu tentang lebih sedikit verbose tetapi saya terinspirasi untuk memaksa berikut ini ke satu baris dengan permintaan satu-liner, tidak tahu seberapa Pythonic itu;)

var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
Dexygen
sumber
3
Mungkin itu seharusnya var enumerableKeysOnThePrototypeChain;)
alex
1
Mungkin kita cukup pintar untuk mengetahui bahwa kita tidak perlu khawatir tentang hasOwnProperty jika objek dibuat sepenuhnya di bawah lingkup kita sebagai lawan diimpor dari tempat lain
Dexygen
tidak pythonic sebagai @ 2 jawaban alex ( for (keys[i++] in foo) {}) meskipun, karena Anda masih melakukan Array.push()(belum lagi mendeklarasikan seluruh fungsi). Implementasi pythonic harus mengandalkan sebanyak mungkin pada pemahaman implisit mungkin, dan gagal itu, menggunakan ekspresi lambda.
cowbert
4

Jika Anda di sini mencari sesuatu untuk mendaftar kunci-kunci objek bersarang n-depth sebagai array datar:

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
sumber
1

Ringkasan

Untuk mendapatkan semua kunci dari Obyek yang dapat Anda gunakan Object.keys(). Object.keys()mengambil objek sebagai argumen dan mengembalikan array semua kunci.

Contoh:

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

Pada contoh di atas kita menyimpan array kunci di const kunci. Kami kemudian dapat dengan mudah mengakses jumlah properti pada objek dengan memeriksa panjang array kunci.

Mendapatkan nilai dengan: Object.values()

Fungsi komplementer Object.keys()adalah Object.values(). Fungsi ini mengambil objek sebagai argumen dan mengembalikan array nilai. Sebagai contoh:

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


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

Willem van der Veen
sumber
1

Jika Anda memutuskan untuk menggunakan Underscore.js sebaiknya Anda lakukan

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