Bir JavaScript nesnesinin özellikleri nasıl listelenir?


842

Diyelim ki bir nesne oluşturuyorum:

var myObject =
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

Mülk adlarının bir listesini almanın en iyi yolu nedir? yani ben bazı değişken 'anahtarları' ile sonuçlandırmak istiyorum ki:

keys == ["ircEvent", "method", "regex"]

3
Biraz konu dışı, ancak underscore.js kullanıyorsanız:_.keys(myJSONObject)
Endy Tjahjono 28:13

Yanıtlar:


1076

Modern tarayıcılarda (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) yerleşik Object.keys yöntemini kullanabilirsiniz:

var keys = Object.keys(myObject);

Yukarıda tam bir çoklu dolgu var, ancak basitleştirilmiş bir versiyon:

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

Alternatif olarak , herhangi bir nesneyi çağırmanıza izin vermek için var getKeysile değiştirin . Prototipin genişletilmesinin bazı yan etkileri vardır ve bunu tavsiye etmem.Object.prototype.keys.keys()


17
Tekrar 'prototip nesnesine bunu yapmak için cazip olabilirsiniz ... ama yapma!'
AnthonyWJones

4
Herkes ışık tutmak isteyecekse, neden Object prototipine fonksiyon eklemeniz önerilmez?
Vishwanath

2
Bu kendi başına tamamen farklı bir soru, burada stackoverflow veya google'da hızlı bir arama size bol bol okuma sağlayacak
ximi

3
for (var key in myObject) {...}Teknik dışarıda tarayıcılar ve V8 JavaScript çalışma süreleri için yararlıdır. Örneğin, javascript eşleme azaltma sorgularını Riak'a geçirirken Objectnesne mevcut olmadığından Object.keysyöntem kullanılamaz.
ekillaby

19
@slashnick "Basitleştirilmiş sürümünüz", nesnenin prototip zincirindeki tüm özellikleri döndürür ("for ... in" kullanıyor gibi), (ECMAScript 5.1) Object.keysyöntemi yalnızca nesnenin kendi özelliklerini döndürür. Bunu önemli bir ayrım olarak görüyorum.
Martin Carel

255

Slashnick'in işaret ettiği gibi , "for in" yapısını, öznitelik adları için bir nesne üzerinde yineleme yapmak için kullanabilirsiniz. Ancak, nesnenin prototip zincirindeki tüm öznitelik adlarını yineleyeceksiniz. Yalnızca nesnenin kendi öznitelikleri üzerinden yineleme yapmak istiyorsanız, Object # hasOwnProperty () yöntemini kullanabilirsiniz. Böylece aşağıdakilere sahip.

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}

25
Keşke bunu slashnic'in cevabından önce okumuş olsaydım. escAnahtarın basılı tutulması için sadece 15 dakika harcamak zorunda kaldım çünkü nesnenin çoğu kullanılmayan yaklaşık bir milyon özelliği vardı ve üzerinde bir uyarı vardı.
Mark Henderson

İşte Zakas'ın konuyla ilgili mükemmel bir makale: nczonline.net/blog/2010/07/27/…
Pablo Cabrera

4
LOL @MarkHenderson - ancak bir dahaki sefere, tarayıcının sürecini öldürün ve 15 dakika boşa harcamak yerine yeniden başlatın :)
JD Smith

İlgili bir işlev obj.getOwnPropertyNames () - geliştirici.mozilla.org/
Steve Goodman

@MarkHenderson Neden console.log kullanmıyorsunuz?
Android

102

Sam Dutton'un yanıtladığı gibi, bu amaç için yeni bir yöntem ECMAScript 5. Baskıda tanıtıldı. Object.keys()istediğinizi yapar ve Firefox 4 , Chrome 6, Safari 5 ve IE 9'da desteklenir .

Yöntemi, desteklemeyen tarayıcılara da kolayca uygulayabilirsiniz. Ancak, bazı uygulamalar Internet Explorer ile tam uyumlu değildir. İşte daha uyumlu bir çözüm:

Object.keys = Object.keys || (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
        DontEnums = [ 
            'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
            'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
        ],
        DontEnumsLength = DontEnums.length;

    return function (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");

        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }

        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }

        return result;
    };
})();

Şu anda kabul edilen yanıtın hasOwnProperty () için bir denetim içermediğini ve prototip zinciri aracılığıyla devralınan özellikleri döndüreceğini unutmayın. Ayrıca, Internet Explorer'daki prototip zincirindeki numaralandırılamayan özelliklerin aynı adla yerel olarak bildirilen özelliklerin DontEnum özniteliklerini devralmasına neden olduğu ünlü DontEnum hatasını da hesaba katmaz.

Object.keys () uygulamak size daha sağlam bir çözüm sağlayacaktır.

EDIT: Prototip iyi bilinen bir katkıda bulunan kanguru ile yakın zamanda yapılan bir tartışma sonrasında , buradaObject.forIn() bulunan işlevi için kod dayalı DontEnum hata için geçici çözüm uyguladı .


Harika cevap, kabul edilen cevabın, her zaman bir JSON dict olduğunu varsayarak, en performanslı doğru çözüm olduğunu düşünüyorum. Bu kesinlikle başka bir yerde kullanmaktır.
David Snabel-Caunt

1
@David Caunt: Teşekkürler :-) Ne yazık ki, kabul edilen cevap hala DontEnum hata faul düşecek ve hangi JSON nesnesi anahtarlarından biri olarak "valueOf" veya "yapıcı" gibi bir dize olabilir asla bilemezsiniz. Ayrıca, uzantılar üzerinden yinelenir Object.prototype. Bununla birlikte, genellikle, daha kısa kodun daha büyük, daha sağlam koddan önemli ölçüde daha çekici göründüğü, ancak bu cevabın amacı Object.keys(), bu kodu kullanarak desteklemeyen tarayıcılarda uygulanabilen ECMAScript 5'i kullanmaktır. Yerel sürüm bundan daha da performanslıdır.
Andy E

2
Çok güzel, Andy :) Sadece hatırlatmak istiyorum - kimse bu iş parçacığından bahsetmek gibi görünüyor - ES5 Object.keyssadece bir nesnenin numaralandırılabilir özelliklerine karşılık gelen dizeleri bir dizi döndürür . Bu, yerel (kullanıcı tanımlı) nesnelerle çalışırken önemli olmayabilir, ancak ana bilgisayar nesneleriyle çok görünür olmalıdır (belirtilmemiş ana bilgisayar nesnelerinin davranışı ayrı - ağrılı - bir hikaye olsa da). TÜM (numaralandırılamayan özellikler) üzerinde numaralandırma yapmak için ES5 şunları sağlar Object.getOwnPropertyNames( uyumluluk tablomdaki desteğe bakın - kangax.github.com/es5-compat-table )
kangax


2
Birisi bunun neden uygulandığını Object.keys(stuff)ve uygulanmadığını açıklayabilir stuff.keys()mi?
Blazemonger

32

Object.keys ve diğer ECMAScript 5 yöntemlerinin Firefox 4, Chrome 6, Safari 5, IE 9 ve üstü tarafından desteklendiğini unutmayın.

Örneğin:

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

ECMAScript 5 uyumluluk tablosu: http://kangax.github.com/es5-compat-table/

Yeni yöntemlerin açıklaması: http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/


Ayrıca Chrome Dev Tools, Firebug, vb. İçin konsoldaki tuşları () kontrol edin
Sam Dutton


28

Object.getOwnPropertyNames(obj)

Bu işlev, ile gösterilenlere ek olarak numaralandırılamayan özellikleri de gösterir Object.keys(obj).

JS'de her mülk, bir boole dahil olmak üzere birkaç özelliğe sahiptir enumerable.

Genel olarak, numaralandırılamayan özellikler daha "içsel" ve daha az kullanılır, ancak gerçekten neler olup bittiğini görmek için bazen onlara bakmak içgörü sahibidir.

Misal:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})

console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

console.log(Object.keys(o))
// [ 'yes' ]

for (var x in o)
    console.log(x)
// yes, base

Ayrıca aşağıdakilere de dikkat edin:

  • Object.getOwnPropertyNamesve Object.keys yok bulmak için prototip zincirini kadar gitmekbase
  • for in yapar

Burada prototip zinciri hakkında daha fazla bilgi: https://stackoverflow.com/a/23877420/895245


16

Döküm fonksiyonunun büyük bir hayranıyım.

http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion alternatif metin


1
+1 çünkü buraya benzer bir şey inşa etmek niyetindeydim (iyi olmasa da).
Camilo Martin

1
netgrow.com.au/assets/files/dump/dump.zip bulunamadı Döküm javascriptini nasıl indirebilirim?
Kiquenet

@Kiquenet Böyle bir şey inşa etmek istediğim her seferinde normal nesne denetçisine yerleşiyorum, HTML'de işlenmesini istiyorsanız npm modülleri gibi şeyler var . Açıkçası beni sıkıştıran şey, bu görüntüde olandan daha iyi bir şey istememdi ama asla kavramsallaştırmayı başaramadı. Müfettişteki nesnelere göz atmak boktan ama keyfi nesnelerden anlam çıkarmak için sezgisel tarama (örneğin, nesne dizilerini sütunlu tablolara ayırmak) her zaman pratikte işe yaramaz.
Camilo Martin

Hakkında ne oluyor Pretty JavaScript Baskı https://j11y.io/demos/prettyprint/ ?
Kiquenet

13

Aşağıdaki gibi jQuery ile yapabilirdi:

var objectKeys = $.map(object, function(value, key) {
  return key;
});

9

yalnızca öğ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 uygulamamın bir parçası ve sadece anahtarları istiyorum, "bu" anahtarları içeren hashmap nesnesidir


8

Bu, IE8'de bile çoğu tarayıcıda çalışır ve herhangi bir tür kitaplığa gerek yoktur. var i senin anahtarın.

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);

2
Cevabınız zaten gönderilenlere benziyor, eklemek için başka bir şey var mı?
VKen

7

Js 1.8'i destekleyen tarayıcılar altında:

[i for(i in obj)]

7

Mozilla, desteklenmediği bir tarayıcıda nasıl yapılacağına ilişkin tüm uygulama ayrıntılarına sahiptir , bu yardımcı olur:

if (!Object.keys) {
  Object.keys = (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

      var result = [];

      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.push(prop);
      }

      if (hasDontEnumBug) {
        for (var i=0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
        }
      }
      return result;
    };
  })();
}

İstediğiniz gibi ekleyebilirsiniz, ancak muhtemelen extensions.jskomut dosyası yığınınızın üst kısmındaki bir tür dosyaya ekleyebilirsiniz.


MDN uygulaması, zaten bir cevap olarak verilen Andy E'lere dayanmaktadır.
outis

5

kullanım Reflect.ownKeys()

var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]

Object.keys ve Object.getOwnPropertyNames numaralandırılamayan özellikler alamıyor . Numaralandırılamayan özellikler için bile çalışıyor .

var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]


4

Kullandığım yana underscore.js hemen her projede, ben kullanırım keysişlevi:

var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));

Bunun çıktısı:

['name', 'hello']

Sık kullanılan javascript işlevselliği için bir araç seti kitaplığıdır: underscorejs.org
schmijos

4

Kabul edilen cevap üzerine inşa.

Nesne aramak istediğiniz özelliklere sahipse demek .properties () deneyin!

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}

0

Çözüm, vakalarımda ve çapraz tarayıcıda çalışıyor:

var getKeys = function(obj) {
    var type = typeof  obj;
    var isObjectType = type === 'function' || type === 'object' || !!obj;

    // 1
    if(isObjectType) {
        return Object.keys(obj);
    }

    // 2
    var keys = [];
    for(var i in obj) {
        if(obj.hasOwnProperty(i)) {
            keys.push(i)
        }
    }
    if(keys.length) {
        return keys;
    }

    // 3 - bug for ie9 <
    var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
    if(hasEnumbug) {
        var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
            'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];

        var nonEnumIdx = nonEnumerableProps.length;

        while (nonEnumIdx--) {
            var prop = nonEnumerableProps[nonEnumIdx];
            if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                keys.push(prop);
            }
        }

    }

    return 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.