Bir javascript nesnesindeki öğe sayısı


104

JavaScript nesnesindeki öğelerin sayısını (bir yerden) almanın bir yolu var mı? (yani sabit zamanlı karmaşıklık).

Bu bilgiyi alan bir özellik veya yöntem bulamıyorum. Şimdiye kadar sadece tüm koleksiyon boyunca bir yineleme yapmayı düşünebiliyorum, ama bu doğrusal zaman.
Nesnenin boyutuna doğrudan erişimin olmaması garip, sence de öyle değil.

DÜZENLEME: Nesneden
bahsediyorum Object(genel olarak nesnelerden değil):

var obj = new Object ;

5
Zaten cevabı burada stackoverflow.com/questions/126100/... Object.keys (obj) .length
tozluk

Yanıtlar:


155

JS uygulamaları bu tür bir değeri dahili olarak takip etse de, onu elde etmenin standart bir yolu yoktur.

Geçmişte, Mozilla'nın Javascript varyantı standart olmayanı__count__ açığa çıkardı, ancak 1.8.5 sürümüyle kaldırıldı.

Tarayıcılar arası komut dosyası oluşturma için, özellikleri açıkça yinelemek ve hasOwnProperty()şunları kontrol etmek zorunda kalıyorsunuz :

function countProperties(obj) {
    var count = 0;

    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
            ++count;
    }

    return count;
}

ECMAScript 5 özellikli uygulamalar olması durumunda, bu şu şekilde de yazılabilir ( Avi Flax'a Tebrikler )

function countProperties(obj) {
    return Object.keys(obj).length;
}

Ayrıca numaralandırılamayan özellikleri (örneğin bir dizinin length) gözden kaçıracağınızı unutmayın .

JQuery, Prototype, Mootools, $ en yeni ne olursa olsun gibi bir çerçeve kullanıyorsanız, kendi koleksiyon API'leriyle gelip gelmediklerini kontrol edin; bu, sorununuza yerel JS nesnelerini kullanmaktan daha iyi bir çözüm olabilir.


11
Lanet olsun her zaman hasOwnProperty'yi unutuyorum. .NET topraklarında çok fazla zaman var sana söylüyorum. +1
annakata

2
jQuery, koleksiyonları için sorgulardan aldığı bir nesneyi kullanır ve bu değeri bir length özelliğiyle ortaya çıkarır.
Nosredna

6
Firefox4 __count__gitti :(
Timo Huovinen

1
Giriş olmadan bunu yapmanın bir yolu var mı? Ben de aynı türden bir bağ içindeyim ama mümkünse JSLint'i geçmesini istiyorum.
sokak lambası

1
neden ihtiyacımız var hasOwnProperty()?
swisswiss

100

Bunu ES5 uyumlu herhangi bir ortamda yapmak için

Object.keys(obj).length

(Tarayıcı desteği buradan )
(Document on Object.keys burada , ECMA5 olmayan tarayıcılara ekleyebileceğiniz yöntemi içerir)


2
Bu cevabı sormak için doğru soru bu değil. Bununla, nesnenin tüm anahtarlarını alıp, onları yeni oluşturulmuş bir diziye yerleştirir ve ardından bu yeni diziden length özelliğini alırsınız.
GetFree

13
Programatik olarak en verimli olmayabilir, ancak geliştirici açısından en verimli olanıdır.
süper parlak ışık

9

Eğer yapınızda zaten jQuery kullanıyorsanız, sadece şunu yapın:

$(yourObject).length

Benim için nesneler üzerinde iyi çalışıyor ve zaten bağımlılık olarak jQuery'ye sahiptim.


5
Garip ... bu benim için çalışmıyor. Her zaman 1 alıyorum. ZelkiN'in cevabı benim için çalışıyor.
mike kemirgen

3
Bu kod her zaman 1 döndürür. Sadece 1 nesne.
İçindeki

5
function count(){
    var c= 0;
    for(var p in this) if(this.hasOwnProperty(p))++c;
    return c;
}

var O={a: 1, b: 2, c: 3};

count.call(O);

2

AFAIK, bir diziye geçmediğiniz sürece bunu güvenilir bir şekilde yapmanın bir yolu yoktur. Hangi dürüst, gelmez garip - bu diziler sayılabilir olduğunu bana oldukça yalındır görünüyor, ve nesneler değildir.

Muhtemelen alacağın en yakın şey böyle bir şey

// Monkey patching on purpose to make a point
Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this ) i++;
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 3

Ancak bu, sorunlar veya en azından sorular yaratır. _Length işlevinin kendisi de dahil olmak üzere, kullanıcı tarafından oluşturulan tüm özellikler sayılır! Ve bu basit örnekte sadece normal bir işlevi kullanarak bundan kaçınabilirsiniz, ancak bu, diğer komut dosyalarının bunu yapmasını engelleyebileceğiniz anlamına gelmez. ee ne yapıyorsun? İşlev özellikleri yoksayılsın mı?

Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this )
  {
      if ( 'function' == typeof this[p] ) continue;
      i++;
  }
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 2

Sonunda, sanırım nesnelerinizi sayılabilir yapma fikrinden vazgeçmeniz ve yaptığınız her şeyi yapmanın başka bir yolunu bulmanız gerektiğini düşünüyorum.


8
TEHLİKE ROBINSON OLACAK! Do DEĞİL Nesne karşı proto! Her şey Object'ten geliyor, büyük miktarda JS çalışması yapıyorsanız, istemcinin bu şekilde işlemesini engelleyeceksiniz.
annakata

5
Uh ... "Bir noktaya değinmek için kasıtlı olarak maymun yamalıyor" yorumunda yazdığım kısmı okumadın mı - hadi, bunu kasıtlı olarak yaptım ki insanlar bu konuda birazcık takla atmasınlar. Ayrıca, maymun yamasını savunmasam
Peter Bailey

Yani .. bu bir yapmak mı yoksa yapmamak mı?
OscarRyz

"Javascript: The Good Parts" da, nesneyi "create ()" yöntemiyle prototipler. Bunun Javascript üzerine kesin kitap olduğuna inanıyorum.
Chris Dutrow

1

Sayı / uzunluk / boyutluluk kavramı bir Nesne için gerçekten mantıklı değil ve buna ihtiyaç duymak bana gerçekten bir Dizi istediğinizi gösteriyor.

Düzenleme: Bunun için bir O (1) istediğinizi bana belirtti. Bildiğim kadarıyla korkarım böyle bir yol yok.


Kendini yinelemeyi önerdi, ki bu çözüm. O ... bunu başarmak için (1) yolu bir O gerekli
Thomas Hansen

Oldukça haklısın. Gerçekten soruları daha detaylı okumalıyım.
annakata

Aslında Nesneler, JS'de bir Haritaya en yakın şeydir. Haritaların uzunluğu vardır.
Cristian Vrabie
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.