Bir karma anahtarları nasıl bulunur?


192

Javascript nesneleri karma olarak çift biliyorum ama anahtarları almak için yerleşik bir işlev bulamadık

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

Gibi bir şey istiyorum

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

Öğeler üzerinde yineleme yapmak ve anahtarları döndürdüğüm bir diziye eklemek için kendime bir işlev yazmak basit, ancak bunu yapmak için standart bir temiz yol var mı?

Kaçırdığım basit bir yerleşik fonksiyon olması gerektiğini hissediyorum ama bulamıyorum!


Ben sadece javascript içine atlamak ama bu yazı size yardımcı olabilir. dean.edwards.name/weblog/2006/07/enum
jason saldo


1
Değerleri anahtarlardan almaya ne dersiniz? Ayrıca, bir karma anahtar sayısı almak.
zero_cool

2017 yanıtı: Object.keys (h) Object.values ​​(h)
17:35

Yanıtlar:


274

Modern JavaScript'te (ECMAScript 5) Object.keysbu işlemi gerçekleştirme işlevi vardır:

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

Uyumluluk ayrıntıları burada bulunabilir .

On Mozilla sitesinde geriye dönük uyumluluk için bir pasajı da var:

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

bu daha doğal olmaz mıydı? 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
Anladığım kadarıyla bu Object.prototype.keys, keystüm Object alt sınıflarına, dolayısıyla tüm nesneler için kullanılabilir olacaktır. Hangi muhtemelen OOP kullanmaya çalışıyorsanız. Her neyse, bu gerçekten gereksinimlerinize bağlıdır.
Ivan Nevostruev

1
Mootools kullanıyorsanız, Object.keys () tüm tarayıcılarda kullanılabilir olmalıdır.
thepeer

Bunu açısal şablonlarda kullanacak bir şey var mı? Orada parsiyeller içinde çalışmıyor.
Jay Shukla

Bu kod örneği ile ayrı bir soru olarak sormak gerektiğini düşünüyorum.
Ivan Nevostruev

80

İstemci tarayıcıları ile büyük bir uyumluluk gerektiren üretim kodu için, Ivan Nevostruev'in yukarıdaki Object.keyseski tarayıcılarda emin olmak için şim ile cevabını hala öneriyorum . Ancak ECMA'nın yeni definePropertyözelliğini kullanarak istenen işlevselliği tam olarak elde etmek mümkündür .

ECMAScript 5 itibarıyla - Object.defineProperty

ECMA5'ten itibaren Object.defineProperty()numaralandırılamayan özellikleri tanımlamak için kullanabilirsiniz . Geçerli uyumluluk hala çok arzulanan vardır, ancak bu sonuçta tüm tarayıcılarda kullanılabilir haline gelmelidir. (Özellikle IE8 ile mevcut uyumsuzluğa dikkat edin!)

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"]

Bununla birlikte, ECMA5 zaten eklendiğinden, Object.keysşunları da kullanabilirsiniz:

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

Orijinal cevap

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

Düzenleme: Bu yanıt bir süredir olduğu için yukarıdakileri el değmeden bırakacağım. Bunu okuyan herkes, Ivan Nevostruev'in aşağıdaki cevabını da okumalıdır.

Prototip işlevlerini numaralandırmanın bir yolu yoktur, bu da onları her zaman kullanmayan in-in döngülerinde ortaya çıkarır hasOwnProperty. Object'in prototipini genişletmek o kadar dağınık olmasa bile bu cevabın ideal olacağını düşünüyorum.


9
'hasOwnProperty', bu nesnenin prototiplerinde bilinmesi yararlı olan özellikleri hariç tutar.
ijw

2
Cevap kabul edildi, çünkü bunu böyle uyguladım ama bunun dilin yerleşik bir işlevi olması gerektiğini hissediyorum.
Pat

5
Genel değişken oluşturmaktan kaçınmak için "for (buradaki var i ... ...") kullanmanız gerektiğini unutmayın.
Brad G.

5
Object.prototype'i değiştirmekten kaçınırım - aşağıda belirtilen başka bir yorumcu olarak, bu kolayca hasOwnProperty () denetimi konusunda dikkatli olmayan komut dosyalarını bozabilir. Bunun yerine, daha az OO dostu bir yöntem kullanın: henüz yoksa bir 'tuşlar' işlevi tanımlayın. (Firefox ve Chrome, OP'nin tam olarak istediği şeyi yapan yerel anahtarlar () işlevini uygular - IE istemez)
digitalbath

1
Object.prototype'e, her normal döngüyü bozduğu için: - son derece yaygındır. Örneğin, Matthew Darwin'in aşağıdaki cevabına göre Google Haritalar'ı ihlal ediyor.
Sam Watkins

42

kullanabilirsiniz Object.keys

Object.keys(h)

3
ECMAScript 5'te eklendi, ancak şu ana kadar çoğu tarayıcıda çalışmalı
Pat

33

Bir Javascript yardımcı programı kütüphanesi olan Underscore.js'yi kullanabilirsiniz .

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

Peki, gerçekten sorulan şey değil, çünkü @Pat yerleşik bir işlev arıyor, ancak yine de ilginç bir kütüphane ve değişmiyorObject.prototype
fresskoma

2
Bugünlerde, bu şık küçük kütüphane izinlerini kendi uygulamalarınızı yazmaya devam etmekten çok daha yararlı olduğunu düşünüyorum ... Her neyse, çoğu gerçek dünya projesinde, yine de Undercore veya eşdeğer kütüphaneleri kullanıyoruz. Şahsen ben Underscore ile gitmek istiyorum.
kumarharsh

_.keys(obj).lengthherhangi bir anahtar olup olmadığını görmek için.
chovy

13

Bildiğim kadarıyla yapabileceğiniz en iyi şey bu ...

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

2
Object.prototype ile uğraştığında da çalışmaz.
Phil

4
Bunu kullanmak ve Object.prototype ile "karıştırmamak" daha iyi olur. Görünüşe göre Object.prototype'e bir şeyler eklersek her şey kırılır: bir dizi / nesnenin anahtarları üzerinde döngü yapmak son derece yaygın bir deyimdir.
Sam Watkins

8

jQuery kullanarak aşağıdaki gibi anahtarları alabilirsiniz:

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

Veya:

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

@pimlottc sayesinde


3
Bu rotaya gitmek istiyorsanız, aşağıdakileri de kullanabilirsiniz JQuery.map:$.map(h, function(v,k) { return k; });
pimlottc

6

Ben in / in kullanarak nesnenin özellikleri arasında döngü inanıyorum, böylece böyle bir şey yapabilir:

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

4

Yukarıdaki en yüksek puan alan cevabı kullanmak istedim

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

Ancak, google maps API v3 ile birlikte kullanıldığında, google maps işlevsel değildir.

for (var key in h) ...

iyi çalışıyor.


1

sadece öğeleri almaya çalışıyorsanız, ancak fonksiyonları almıyorsanız, bu kod size yardımcı olabilir

this.getKeys = function() {

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

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

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

}

Bu benim HashMap benim uygulamasının bir parçasıdır ve sadece anahtarları istiyorum, anahtarları thisiçeren hashmap nesnesidir

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.