Bagaimana menemukan kunci hash?


192

Saya tahu di objek javascript berfungsi ganda sebagai hash tetapi saya tidak dapat menemukan fungsi bawaan untuk mendapatkan kunci

var h = {a:'b',c:'d'};

Saya menginginkan sesuatu seperti

var k = h.keys() ; // k = ['a','c'];

Sangat mudah untuk menulis fungsi sendiri untuk beralih item dan menambahkan kunci ke array yang saya kembalikan, tetapi apakah ada cara pembersih standar untuk melakukan itu?

Saya terus merasa itu pasti fungsi bawaan yang saya lewatkan tetapi saya tidak dapat menemukannya!


Saya baru saja beralih ke javascript tetapi posting ini dapat membantu Anda. dean.edwards.name/weblog/2006/07/enum
jason saldo

Kemungkinan duplikat Dapatkan larik kunci objek
blo0p3r

1
Bagaimana dengan mendapatkan nilai dari kunci? Juga, mendapatkan jumlah kunci dalam hash.
zero_cool

Jawaban 2017: Object.keys (h) Object.values ​​(h)
losty

Jawaban:


274

Ada fungsi dalam JavaScript modern (ECMAScript 5) yang disebut Object.keysmelakukan operasi ini:

var obj = { "a" : 1, "b" : 2, "c" : 3};
alert(Object.keys(obj)); // will output ["a", "b", "c"]

Detail kompatibilitas dapat ditemukan di sini .

Di situs Mozilla ada juga cuplikan untuk kompatibilitas mundur:

if(!Object.keys) Object.keys = function(o){
   if (o !== Object(o))
      throw new TypeError('Object.keys called on non-object');
   var ret=[],p;
   for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p);
   return ret;
}

bukankah ini lebih alami? if(!Object.prototype.keys) Object.prototype.keys = function() { if (this !== Object(this)) throw new TypeError('Object.keys called on non-object'); var ret = [], p; for (p in this) if (Object.prototype.hasOwnProperty.call(this, p)) ret.push(p); return ret; } var x = { a: { A: 1, B: 2, C: 3 }, b: { A: 10, B: 20 } }; alert(x.a.keys());
ekkis

2
Seperti yang saya pahami ini Object.prototype.keys akan keystersedia untuk semua sub-kelas Object, oleh karena itu untuk semua objek. Yang mungkin Anda inginkan jika Anda mencoba menggunakan OOP. Bagaimanapun ini sangat tergantung pada kebutuhan Anda.
Ivan Nevostruev

1
Jika Anda menggunakan mootools, Object.keys () harus tersedia di semua browser.
si kucing

Apakah ada yang bisa digunakan dalam template bersudut? Itu tidak bekerja di sana di dalam parsial.
Jay Shukla

Saya pikir Anda harus mengajukan ini sebagai pertanyaan terpisah dengan contoh kode.
Ivan Nevostruev

80

Untuk kode produksi yang membutuhkan kompatibilitas besar dengan browser klien saya masih menyarankan jawaban Ivan Nevostruev di atas dengan shim untuk memastikan Object.keysdi browser yang lebih lama. Namun, dimungkinkan untuk mendapatkan fungsionalitas tepat yang diminta menggunakan ECMA yang barudefineProperty fitur .

Pada ECMAScript 5 - Object.defineProperty

Pada ECMA5 Anda dapat menggunakan Object.defineProperty()untuk mendefinisikan properti yang tidak dapat dihitung. The kompatibilitas saat masih banyak yang harus diinginkan, tapi ini akhirnya harus menjadi digunakan di semua browser. (Secara khusus catat ketidakcocokan saat ini dengan IE8!)

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    var keys = [];
    for(var i in this) if (this.hasOwnProperty(i)) {
      keys.push(i);
    }
    return keys;
  },
  enumerable: false
});

var o = {
    'a': 1,
    'b': 2
}

for (var k in o) {
    console.log(k, o[k])
}

console.log(o.keys())

# OUTPUT
# > a 1
# > b 2
# > ["a", "b"]

Namun, karena ECMA5 sudah menambahkan Object.keysAnda mungkin juga menggunakan:

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    return Object.keys(this);
  },
  enumerable: false
});

Jawaban asli

Object.prototype.keys = function ()
{
  var keys = [];
  for(var i in this) if (this.hasOwnProperty(i))
  {
    keys.push(i);
  }
  return keys;
}

Edit: Karena jawaban ini sudah ada untuk sementara waktu, saya akan membiarkan jawaban di atas tidak tersentuh. Siapa pun yang membaca ini juga harus membaca jawaban Ivan Nevostruev di bawah ini.

Tidak ada cara untuk membuat fungsi prototipe non-enumerable yang mengarah pada mereka selalu muncul di loop for-in yang tidak digunakan hasOwnProperty. Saya masih berpikir jawaban ini akan ideal jika memperluas prototipe Object tidak begitu berantakan.


9
'hasOwnProperty' mengecualikan properti pada prototipe objek ini, yang berguna untuk diketahui.
ijw

2
Jawaban diterima karena itulah bagaimana saya akhirnya mengimplementasikannya tetapi saya merasa ini seharusnya merupakan fungsi bawaan dari bahasa tersebut.
Pat

5
Perhatikan bahwa Anda harus menggunakan "for (var i in this) ..." untuk menghindari membuat variabel global.
Brad G.

5
Saya akan menghindari memodifikasi Object.prototype - seperti komentator lain yang disebutkan di bawah, ini dapat dengan mudah memecahkan skrip yang tidak hati-hati memeriksa hasOwnProperty (). Alih-alih, gunakan cara yang kurang ramah-OO: tentukan fungsi 'kunci' jika belum ada. (Firefox dan Chrome sama-sama menerapkan fungsi tombol asli () yang melakukan persis apa yang diinginkan OP - IE tidak)
digitalbath

1
Tampaknya ide yang buruk untuk menambahkan sesuatu ke Object.prototype, karena ia merusak setiap loop normal seperti: untuk (var k dalam array) {} atau untuk (var k dalam objek), dan idiom itu - meskipun mungkin salah - sangat umum. Misalnya menurut jawaban Matthew Darwin di bawah ini, Google Maps rusak.
Sam Watkins

42

kamu bisa memakai Object.keys

Object.keys(h)

3
Ditambahkan dalam ECMAScript 5 tetapi harusnya berfungsi di sebagian besar browser utama sekarang
Pat

33

Anda bisa menggunakan Underscore.js , yang merupakan pustaka utilitas Javascript.

_.keys({one : 1, two : 2, three : 3}); 
// => ["one", "two", "three"]

Yah, itu tidak benar-benar apa yang diminta, karena @Pat mencari fungsi built-in, tapi itu adalah perpustakaan yang menarik, dan itu tidak memodifikasiObject.prototype
fresskoma

2
Saat ini, saya pikir jauh lebih bermanfaat untuk menggunakan pustaka kecil yang bagus ini — daripada terus menulis implementasi Anda sendiri ... Bagaimanapun, di sebagian besar proyek dunia nyata, kami juga menggunakan Underscore atau pustaka yang setara. Secara pribadi, saya lebih suka menggunakan Underscore.
kumarharsh

_.keys(obj).lengthuntuk melihat apakah ada kunci.
chovy

13

Ini yang terbaik yang bisa Anda lakukan, sejauh yang saya tahu ...

var keys = [];
for (var k in h)keys.push(k);

2
Ini juga tidak berfungsi ketika Object.prototype telah dikacaukan.
Phil

4
Akan lebih baik untuk menggunakan ini, dan tidak "mengacaukan" Object.prototype. Tampaknya semuanya rusak jika kita menambahkan sesuatu ke Object.prototype: ini adalah ungkapan yang sangat umum untuk mengulangi kunci-kunci array / objek.
Sam Watkins

8

menggunakan jQuery Anda bisa mendapatkan kunci seperti ini:

var bobject =  {primary:"red",bg:"maroon",hilite:"green"};
var keys = [];
$.each(bobject, function(key,val){ keys.push(key); });
console.log(keys); // ["primary", "bg", "hilite"]

Atau:

var bobject =  {primary:"red",bg:"maroon",hilite:"green"};
$.map(bobject, function(v,k){return k;});

terima kasih kepada @pimlottc


3
Jika Anda ingin menempuh rute ini, Anda sebaiknya menggunakan JQuery.map: $.map(h, function(v,k) { return k; });
pimlottc

6

Saya percaya Anda dapat mengulangi properti yang digunakan objek untuk / di, sehingga Anda dapat melakukan sesuatu seperti ini:

function getKeys(h) {
  Array keys = new Array();
  for (var key in h)
    keys.push(key);
  return keys;
}

4

Saya ingin menggunakan jawaban berperingkat teratas di atas

Object.prototype.keys = function () ...

Namun saat digunakan bersamaan dengan google maps API v3, google maps tidak berfungsi.

for (var key in h) ...

bekerja dengan baik.


1

jika Anda mencoba untuk mendapatkan elemen saja tetapi bukan fungsinya maka kode ini dapat membantu Anda

this.getKeys = function() {

var keys = new Array();
for(var key in this) {

    if( typeof this[key] !== 'function') {

        keys.push(key);
    }
}
return keys;

}

ini adalah bagian dari implementasi HashMap saya dan saya hanya ingin kunci, thisadalah objek hashmap yang berisi kunci

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.