2009-08-28 17 views
138

Załóżmy, że mam następujący obiekt w JavaScript:Jak liczyć atrybuty obiektu JavaScript?

var object = { 
    "key1": "value1", 
    "key2": "value2", 
    "key3": "value3" 
}; 

Jak mogę dowiedzieć się, ile wartości istnieją w obiekcie?

+7

Trzymaj się! JS nie ma krotek i słowników. To się nazywa obiekt (zapisany w dosłownym zapisie), chociaż wygląda jak słownik Pythona. Jak jednak nazywasz krotkę w powyższym przykładzie? –

+0

Jak sugerujesz zmienić nazwę tego pytania? –

+0

Może "atrybuty" zamiast "krotek"? Zakładamy, że chcesz, aby odpowiedź miała 3 z powyższym "obiektem". –

Odpowiedz

97

Nie ma łatwej odpowiedzi, ponieważ każdy obiekt w kodzie JavaScript pochodzi z — automatycznie zawiera wiele atrybutów, a dokładny zestaw atrybutów, które otrzymujesz, zależy od konkretnego interpretatora i od tego, jaki kod został wykonany przed twoją. Musisz więc w jakiś sposób oddzielić te, które zdefiniowałeś od tych, które dostałeś "za darmo".

Oto jeden ze sposobów:

var foo = {"key1": "value1", "key2": "value2", "key3": "value3"}; 
Object.prototype.foobie = 'bletch'; // add property to foo that won't be counted 

var count = 0; 
for (var k in foo) { 
    if (foo.hasOwnProperty(k)) { 
     ++count; 
    } 
} 
alert("Found " + count + " properties specific to foo"); 

Druga linia pokazuje inny kod można dodać właściwości do wszystkich Object pochodnych. Jeśli usuniesz test hasOwnProperty() w pętli, liczba właściwości zwiększy się do co najmniej 4. Na stronie z innym kodem JavaScript oprócz tego kodu, może być wyższa niż 4, jeśli ten inny kod również modyfikuje prototyp Object.

+2

Nie powinieneś używać pustego obiektu, aby uzyskać dostęp do Object.prototype. Po prostu użyj Object.prototype.hasOwnProperty.call (foo, k). –

+0

dlaczego po prostu nie robisz foo.hasOwnProperty (k). Czy czegoś brakuje? Mam na myśli, że nawet typ JavaScript wywodzi się z Object.prototype i będzie miał metodę hasOwnProperty(). – bucabay

+0

@ Elijah: Nie widzę, co jest nie tak z moim sposobem, ale tak, twoja droga też powinna działać. –

11

Można iteracyjne nad obiektem, aby uzyskać klucze lub wartości:

function numKeys(obj) 
{ 
    var count = 0; 
    for(var prop in obj) 
    { 
     count++; 
    } 
    return count; 
}

To wygląda jak „pomyłkę”, ale po prostu chcę podkreślić, że przykład jest nieprawidłowa składnia powinna być

var object = {"key1":"value1","key2":"value2","key3":"value3"}; 

5

Ta funkcja wykorzystuje własność Mozilli __count__, jeśli jest dostępna, ponieważ jest szybsza niż iterowanie po każdej usłudze.

function countProperties(obj) { 
    var count = "__count__", 
    hasOwnProp = Object.prototype.hasOwnProperty; 

    if (typeof obj[count] === "number" && !hasOwnProp.call(obj, count)) { 
    return obj[count]; 
    } 
    count = 0; 
    for (var prop in obj) { 
    if (hasOwnProp.call(obj, prop)) { 
     count++; 
    } 
    } 
    return count; 
}; 

countProperties({ 
    "1": 2, 
    "3": 4, 
    "5": 6 
}) === 3; 
+0

Należy zauważyć, że ten atrybut został uznany za przestarzały w Firefoksie 4 i usunięty wkrótce po nim, dlatego nie był obecny w żadnej przeglądarce przez kilka lat. –

3

EDIT: to będzie uwzględniana wielkość błędów z jQuery stanie, plus kilka innych niedogodności. NIE POWINIENEŚ KORZYSTAĆ Z NIEGO: (być może, gdyby można dodać metodę prywatną zamiast funkcji własności publicznej, byłoby to OK, ale teraz nie ma czasu). Społeczność wikied

nie używać:

Nawet jeśli obiekt JavaScript męska domyślnie nie posiada funkcję zliczania, zajęcia są łatwo rozszerzalne i można je dodać siebie:

Object.prototype.count = function() { 
    var count = 0; 
    for(var prop in this) { 
     if(this.hasOwnProperty(prop)) 
      count = count + 1; 
    } 
    return count; 
} 

tak, że po że można wykonać

var object = {'key1': 'val1', 'key2':'val2', 'key3':'val3'}; 
console.log(object.count()); // 3 

Podsumowując, jeśli chcesz liczyć funkcjonalności obiektów, trzeba skopiować kod z bloku kodu 1 i wklej go na początku i n czas wykonania (przed wywołaniem liczenia).

Daj mi znać, jeśli to działa dla Ciebie!

Pozdrawiam, Pedro

+0

Witam. używam tego przez jakiś czas bez żadnych problemów ... Jedynym problemem, jaki znalazłem, jest to, że jeśli uruchomisz pętlę obiektów po implozji tej właściwości na wszystkich obiektach, wykonasz dodatkową pętlę. Jeśli ktokolwiek może znaleźć obejście, to byłoby świetnie – droope

+0

OGROMNE PROBELMS Z TEN JEDNYM – droope

+0

Dlaczego to jest wiki? – Shaz

-3

Mimo, że nie będzie „prawdziwym przedmiotem”, zawsze można zrobić coś takiego:

var foo = [ 
    {Key1: "key1"}, 
    {Key2: "key2"}, 
    {Key3: "key3"} 
]; 

alert(foo.length); // === 3 
+0

Próbujemy uzyskać długość nieruchomości. Zatem wynik powinien wynosić tylko 1 w twoim przypadku. – Santosh

1

Dla tych, które będą czytać to pytanie/odpowiedź, tutaj jest implementacją JavaScript zbioru słowników bardzo podobną do funkcjonalności.NET jeden: JavaScript Dictionary

44

Użyj biblioteki underscore, bardzo przydatny: _.keys(obj).length.

+3

Wydaje się bardzo przydatna biblioteka. –

+0

Używam tego, bardzo fajnie. Dzięki, Alexander. – Wolf87

+6

Z plikiem underscore.js można użyć _.size (obj). – GijsjanB

12
var miobj = [ 
    {"padreid":"0", "sw":"0", "dtip":"UNO", "datos":[]}, 
    {"padreid":"1", "sw":"0", "dtip":"DOS", "datos":[]} 
]; 
alert(miobj.length) //=== 2 

ale

alert(miobj[0].length) //=== undefined 

funkcja ta jest bardzo dobra

Object.prototype.count = function() { 
    var count = 0; 
    for(var prop in this) { 
     if(this.hasOwnProperty(prop)) 
      count = count + 1; 
    } 
    return count; 
} 

alert(miobj.count()) // === 2 
alert(miobj[0].count()) // === 4 
+0

Witamy!Rozważ nazewnictwo zmiennych i danych w języku angielskim ;-) – atxe

+3

Rozszerzanie obiektów natywnych to zła praktyka. Nie rób tego. – nkm

+0

kiedy używam tego kodu, wtedy lista rozwijana bootstrap nie działa –

421

Można to zrobić za pomocą tego prostego kodu:

Object.keys(myObject).length 
+2

To jest daleki od pełnego wsparcia: http://kangax.github.io/es5-compat-table/ – Andrew

+16

@Andrew Nie powiedziałbym "daleko od pełni" I powiedziałbym, że nie jest obsługiwane w IE8 i poniżej. Ponadto [Polyfill] (http://jsperf.com/polyfill-object-keys). – hitautodestruct

+0

Wystarczająco uczciwe, nie jest obsługiwane w IE8 lub poniżej. Jeśli to jest problem, przetestuj istnienie kluczy() w Object (lub try-catch) i cofnij. – Andrew