Pytanie Długość obiektu JavaScript


Jeśli mam obiekt JavaScript, powiedz

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

czy istnieje wbudowany lub zaakceptowany najlepszy sposób na uzyskanie długości tego obiektu?


1827
2017-08-07 19:42


pochodzenie


Literały obiektowe w javascript są domyślnie tablicami asocjacyjnymi, np. Object.propertyName.propertyValue jest tym samym co object [propertyName] [propertyValue] - neitony
Dodano jedno-liner w pliku Underscore.js, który to robi: stackoverflow.com/a/11346637/11236 - ripper234
Po odpowiedzi na linię użyj Object.keys (myArray). Length jako @aeosynth powiedział. - Ranadheer Reddy
ok, co powiesz Object.keys(obj).length - Muhammad Umer
Dlaczego właściwość object.length nie jest poprawna? Zwraca prawidłowy wynik dla mnie. - Adrian M


Odpowiedzi:


Najbardziej niezawodną odpowiedzią (tzn. Która rejestruje cel tego, co próbujesz zrobić, powodując najmniej błędów) będzie:

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

// Get the size of an object
var size = Object.size(myArray);

Jest taki rodzaj konwencji w JavaScript, który ty nie dodawaj rzeczy do Object.prototype, ponieważ może on łamać wyliczenia w różnych bibliotekach. Dodawanie metod do obiektu jest jednak zazwyczaj bezpieczne.


Oto aktualizacja od 2016 roku i powszechne wdrażanie ES5 i dalej.  Dla IE9 + i wszystkich innych nowoczesnych przeglądarek obsługujących ES5 + możesz użyć Object.keys() więc powyższy kod staje się:

var size = Object.keys(myObj).length;

To nie musi od tego czasu modyfikować żadnego istniejącego prototypu Object.keys() jest teraz wbudowany.

Edytować: Obiekty mogą mieć właściwości symboliczne, których nie można zwrócić za pomocą metody Object.key. Tak więc odpowiedź byłaby niepełna bez wspominania o nich.

Typ symbolu został dodany do języka w celu utworzenia niepowtarzalnych identyfikatorów dla właściwości obiektu. Główną zaletą typu Symbol jest zapobieganie nadpisywaniu.

Object.keys lub Object.getOwnPropertyNames nie działa dla właściwości symbolicznych. Aby je zwrócić, musisz użyć Object.getOwnPropertySymbols.

var person = {
  [Symbol('name')]: 'John Doe',
  [Symbol('age')]: 33,
  "occupation": "Programmer"
};

const propOwn = Object.getOwnPropertyNames(person);
console.log(propOwn.length); // 1

let propSymb = Object.getOwnPropertySymbols(person);
console.log(propSymb.length); // 2

2022
2017-08-09 08:31



@Tres - Twój kod może zostać złamany, jeśli ktoś przyjdzie i przekroczy właściwość "size", nie wiedząc, że zadeklarowałeś go gdzieś w kodzie, więc zawsze warto sprawdzić, czy jest już zdefiniowany - vsync
@vsync Jesteś bardzo poprawny. Zawsze należy wprowadzić niezbędne kontrole poczytalności :) - Tres
Dlaczego wszyscy ignorują to: Object.keys(obj).length - Muhammad Umer
@MuhammadUmer Prawdopodobnie dlatego, że ta metoda nie istniała nawet po napisaniu tej odpowiedzi. Nawet dzisiaj użycie tego będzie prawdopodobnie wymagało użycia funkcji polyfill w starych przeglądarkach. - Chris Hayes
@stonyau IE8, IE9, IE10 to martwe przeglądarki, które nie otrzymują wsparcia od Microsoft. Użytkownik IE8, IE9, IE10 otrzymuje powiadomienie od Microsoft, że używa starej, nieobsługiwanej przeglądarki i powinien oczekiwać, że te rzeczy nie będą dla nich działać. support.microsoft.com/en-us/kb/3123303 - Lukas


Jeśli wiesz, że nie musisz się martwić hasOwnProperty kontrole, możesz to zrobić bardzo prosto:

Object.keys(myArray).length

1413
2018-04-03 01:44



Dlaczego nie? z tego, co wiem, jest to standard: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/... - vsync
To nie jest uniwersalne wdrożony metoda, ale możesz sprawdzić, której przeglądarki obsługuje ten stół. - aeosynth
Brak wsparcia dla IE8 = bez wyjścia. - ripper234
czas na przejście na firefox = niestety zmiana nie oznacza, że ​​użytkownicy twojej strony ... - mdup
@ ripper234 brak wsparcia IE = czas na polyfill - John Dvorak


Zaktualizowano: Jeśli używasz Underscore.js (zalecane, to lekkie!), to możesz po prostu zrobić

_.size({one : 1, two : 2, three : 3});
=> 3

Jeśli nie, i nie chcesz zawracać uwagi właściwościami obiektu z jakiegokolwiek powodu i już używasz jQuery, wtyczka jest jednakowo dostępna:

$.assocArraySize = function(obj) {
    // http://stackoverflow.com/a/6700/11236
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

252
2017-07-05 14:39



_.size() było idealnym rozwiązaniem dla mnie Meteor projekt, który ma obsługę underscore.js. - tokyovariable
Używam podkreślenia, a ten wpis przypomniał mi, że nie używam go wystarczająco w tym projekcie. Jeśli zajmujesz się obiektami, powinieneś mieć dostępny plik underscore.js. - jbolanos
Podkreślenie> (all - ['lo-dash']) - Rayjax
Dostałem też lodash.js  lać - hipkiss
@Babydead, aby odróżnić prawdziwe właściwości obiektu od dziedziczonych. developer.mozilla.org/en/docs/Web/JavaScript/Reference/... - ripper234


Użyj czegoś tak prostego jak:

Object.keys(obj).length

Nie musi to być trudne i zdecydowanie nie wymaga wykonania innej funkcji.


153
2017-10-27 03:46



Czym różni się to od odpowiedzi aeosyntha? - DanMan
Czy widziałeś już liczbę odpowiedzi na to pytanie? Kiedy to napisałem, nie widziałem (kilku) duplikatów. James Coglan odpowiedział w ten sposób na 3 lata przed aeosynth, więc nie przeczytałeś wszystkich odpowiedzi albo ... albo widziałbyś to. - Michael
@ Michael nie, nie zrobił tego. To była zmiana dokonana przez innego użytkownika w dniach 02-28-2016. przejrzeć - old_mountain


Oto najbardziej rozwiązanie dla różnych przeglądarek.

Jest to lepsze niż zaakceptowana odpowiedź, ponieważ używa natywnych Object.keys, jeśli istnieje. Dzięki temu jest najszybszy we wszystkich nowoczesnych przeglądarkach.

if (!Object.keys) {
    Object.keys = function (obj) {
        var arr = [],
            key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                arr.push(key);
            }
        }
        return arr;
    };
}

Object.keys(obj).length;

43
2017-09-01 16:12



Object.keys() zwraca tablicę zawierającą nazwy tylko tych właściwości, które są przeliczalne. Jeśli chcesz mieć tablicę z WSZYSTKIMI właściwościami, powinieneś użyć Object.getOwnPropertyNames() zamiast. Widzieć developer.mozilla.org/en/docs/Web/JavaScript/Reference/... - John Slegers


Nie jestem ekspertem od JavaScript, ale wygląda na to, że musiałbyś przechodzić przez elementy i liczyć je, ponieważ Object nie ma metody length:

var element_count = 0;
for (e in myArray) {  if (myArray.hasOwnProperty(e)) element_count++; }

@palmsey: W uczciwości dla OP, dokumentacja JavaScript wyraźnie odnosi się do używania zmiennych typu Object w ten sposób jako "tablic asocjacyjnych".


27
2017-08-07 19:52



Nie zadziała, ponieważ będzie liczyć metody, które są dodawane przez prototyp. - Lajos Meszaros


Ta metoda pobiera wszystkie nazwy właściwości obiektu w tablicy, dzięki czemu można uzyskać długość tej tablicy, która jest równa długości kluczy obiektu.

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2

25
2017-07-01 12:40



Wolę tę metodę, ponieważ wewnętrznie wywołuje "hasOwnProperty", więc nie przesyła nazw właściwości, które są dziedziczone z łańcucha prototypów, i jest jednolinijką, tak jak Object.keys(...).length ale o wiele bezpieczniej z tego powodu, o którym właśnie powiedziałem. - Patrick Roberts
Metoda @PatrickRoberts keys nie zwraca właściwości z łańcucha prototypów. Więc dlaczego potrzeba hasOwnProperty tutaj. Również getOwnProperty zwróci ukryte właściwości, ponieważ długość jest w tablicy itp. - Muhammad Umer
@MuhammadUmer "Jeśli mam tablicę asocjacyjną JavaScript ..." jest to obiekt, a nie tablica. length jest własnością instancji Array, dlatego należy ją uwzględnić w długości kluczy. I tak, masz rację co do łańcucha prototypów, odwołuję to stwierdzenie. Chciałem powiedzieć, że ogólnie rzecz biorąc, chciałbyś mieć nawet niezliczalne właściwości, jeśli masz obiekt podobny do Arraya, ponieważ tablica ma już lengthwłasność na początek. - Patrick Roberts
działa to w IE-8 - marcusshep