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 sposób najlepszej praktyki, aby uzyskać długość tego obiektu?

Author: Gareth Simpson, 2008-08-07

30 answers

Najbardziej solidną odpowiedzią (tj. która oddaje intencję tego, co próbujesz zrobić, powodując najmniej błędów) byłoby:

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

Istnieje pewien rodzaj konwencji w JavaScript, że nie dodajesz rzeczy do obiektu.prototype , ponieważ może łamać wyliczenia w różnych bibliotekach. Dodawanie metod do obiektu jest jednak zwykle bezpieczne.


Oto aktualizacja z 2016 i powszechne wdrożenie ES5 i dalej. dla IE9+ i wszystkich innych nowoczesne przeglądarki obsługujące ES5+, można użyć Object.keys() więc powyższy kod staje się po prostu:

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

To nie musi modyfikować żadnego istniejącego prototypu, ponieważ Object.keys() jest teraz wbudowany.

Edit : obiekty mogą mieć właściwości symboliczne, które nie mogą być zwracane przez obiekt.kluczowa metoda. Więc odpowiedź byłaby niekompletna, nie wspominając o nich.

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

Object.keys or Object.getOwnPropertyNames nie działa dla właściwości symbolicznych. Aby je zwrócić należy 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
 2082
Author: SnnSnn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-15 21:48:10

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

Object.keys(myArray).length
 1442
Author: aeosynth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-21 20:12:12

Aktualizacja : Jeśli używasz podkreślenia.js (zalecane, jest lekki!), wtedy możesz po prostu zrobić

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

Jeśli nie, i nie chcesz mieszać z właściwościami obiektu z jakiegokolwiek powodu, a już używasz jQuery, wtyczka jest równie 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;
};
 256
Author: ripper234,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-08 10:30:58

Użyj czegoś tak prostego jak:

Object.keys(obj).length

To nie musi być trudne i zdecydowanie nie wymaga innej funkcji do wykonania.

 157
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-17 18:30:01

Oto najlepsze rozwiązanie między przeglądarkami.

Jest to lepsze od zaakceptowanej odpowiedzi, ponieważ używa obiektu natywnego.klucze, jeśli istnieją. Jest więc najszybszy dla wszystkich nowoczesnych przeglądarek.

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;
 45
Author: Joon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-01 16:12:06

Nie jestem ekspertem w JavaScript, ale wygląda na to, że będziesz musiał przechodzić przez elementy i liczyć je, ponieważ obiekt nie ma metody długości:

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

@palmsey: tak naprawdę dokumentacja JavaScript wyraźnie odnosi się do używania zmiennych typu Object w ten sposób jako "tablic asocjacyjnych".

 29
Author: jj33,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-17 18:27:26

Ta metoda pobiera wszystkie nazwy właściwości obiektu w tablicy, więc możesz uzyskać Długość tej tablicy, która jest równa długości kluczy Twojego obiektu.

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2
 26
Author: venkat7668,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-06 19:43:01

Aby nie zadzierać z prototypem lub innym kodem, możesz zbudować i rozszerzyć swój własny obiekt:

function Hash(){
    var length=0;
    this.add = function(key, val){
         if(this[key] == undefined)
         {
           length++;
         }
         this[key]=val;
    }; 
    this.length = function(){
        return length;
    };
}

myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2

Jeśli zawsze używasz metody add, właściwość length będzie poprawna. Jeśli martwisz się, że ty lub inni zapomnieliście o jej użyciu, możesz dodać licznik właściwości, który inni opublikowali również do metody length.

Oczywiście zawsze można nadpisać metody. Ale nawet jeśli to zrobisz, twój kod prawdopodobnie zawiedzie zauważalnie, co ułatwi debugowanie. ;)

 21
Author: DanMan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 01:37:04

Oto jak i nie zapomnij sprawdzić, czy właściwość nie znajduje się w łańcuchu prototypów:

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;
 15
Author: doekman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-23 23:28:42

Oto zupełnie inne rozwiązanie, które będzie działać tylko w bardziej nowoczesnych przeglądarkach (IE9+, Chrome, Firefox 4+, Opera 11.60+, Safari 5.1+)

Zobacz jsFiddle

Konfiguracja klasy tablicy asocjacyjnej

/**
 * @constructor
 */
AssociativeArray = function () {};

// Make the length property work
Object.defineProperty(AssociativeArray.prototype, "length", {
    get: function () {
        var count = 0;
        for (var key in this) {
            if (this.hasOwnProperty(key))
                count++;
        }
        return count;
    }
});

Teraz możesz użyć tego kodu w następujący sposób...

var a1 = new AssociativeArray();
a1["prop1"] = "test";
a1["prop2"] = 1234;
a1["prop3"] = "something else";
alert("Length of array is " + a1.length);
 14
Author: Ally,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-02 09:01:07

W niektórych przypadkach lepiej jest po prostu zapisać rozmiar w osobnej zmiennej. Szczególnie, jeśli dodajesz do tablicy o jeden element w jednym miejscu i możesz łatwo zwiększyć rozmiar. To oczywiście działa znacznie szybciej, jeśli trzeba często sprawdzać rozmiar.

 13
Author: Jānis Elmeris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-29 13:41:54

Użycie:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)
 13
Author: Mahendra Kulkarni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-17 18:36:54

Po prostu użyj tego, aby uzyskać length:

Object.keys(myObject).length
 12
Author: saurabhgoyal795,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 08:27:18

@palmsey: w uczciwości dla OP, dokumenty javascript faktycznie wyraźnie odnoszą się do używania zmiennych typu Object w ten sposób jako "tablice asocjacyjne".

I szczerze mówiąc @palmsey miał rację, to nie są tablice asocjacyjne, to na pewno obiekty:) - wykonujące zadanie tablicy asocjacyjnej. Ale jeśli chodzi o szerszy punkt, zdecydowanie masz do tego prawo zgodnie z tym dość dobrym artykułem, który znalazłem:

JavaScript "Tablice Asocjacyjne" Uznane Za Szkodliwe

Ale zgodnie z tym wszystkim, czy samaprzyjęta odpowiedź nie jest złą praktyką?

Określa funkcję prototype size () dla obiektu

Jeśli coś jeszcze zostało dodane do obiektu .prototype, wtedy sugerowany Kod się nie powiedzie:

<script type="text/javascript">
Object.prototype.size = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
Object.prototype.size2 = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
</script>

Myślę, że odpowiedź nie powinna być zaakceptowana, ponieważ nie można jej ufać, jeśli masz uruchomiony inny kod w tym samym kontekście wykonania. Aby zrobić to w solidny sposób, z pewnością będziesz musiał zdefiniować metodę rozmiaru w myArray i sprawdzić typ Członków podczas iteracji przez nich.

 11
Author: Polsonby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:58

Najprostszym jest Obiekt.klucze (myObject).długość

 10
Author: Tamesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-21 02:25:54

A co z czymś takim --

function keyValuePairs() {
    this.length = 0;
    function add(key, value) { this[key] = value; this.length++; }
    function remove(key) { if (this.hasOwnProperty(key)) { delete this[key]; this.length--; }}
}
 9
Author: Jerry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-24 14:26:28

Jeśli mamy hash

Hash = {"a" : "b", "c": "d"};

Możemy uzyskać długość używając długości kluczy, która jest długością skrótu:

Keys (hash).długość

 9
Author: abo-elleef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-17 18:28:53

Jeśli używasz AngularJS 1.x możesz robić rzeczy w sposób AngularJS, tworząc filtr i używając kodu z dowolnego z innych przykładów, takich jak:

// Count the elements in an object
app.filter('lengthOfObject', function() {
  return function( obj ) {
    var size = 0, key;
    for (key in obj) {
      if (obj.hasOwnProperty(key)) size++;
    }
   return size;
 }
})

Użycie

W Twoim kontrolerze:

$scope.filterResult = $filter('lengthOfObject')($scope.object)

Lub Twoim zdaniem:

<any ng-expression="object | lengthOfObject"></any>
 9
Author: pcnate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-17 18:33:46

Jeśli potrzebujesz asocjacyjnej struktury danych, która ujawnia jej rozmiar, lepiej Użyj mapy zamiast obiektu.

var myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3
 7
Author: Oriol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-18 18:16:07

Wariacją na niektóre z powyższych jest:

var objLength = function(obj){    
    var key,len=0;
    for(key in obj){
        len += Number( obj.hasOwnProperty(key) );
    }
    return len;
};
Jest to nieco bardziej elegancki sposób na integrację hasOwnProp.
 6
Author: wade harrell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-07 10:54:43

Jeśli nie zależy ci na obsłudze przeglądarki Internet Explorer 8 lub niższej, możesz łatwo uzyskać liczbę właściwości w obiekcie, wykonując następujące dwa kroki:

  1. uruchomić albo Object.keys() aby uzyskać tablicę zawierającą nazwy tylko tych właściwości, które są enumerable lub Object.getOwnPropertyNames() jeśli chcesz również dołączyć nazwy właściwości, które nie są możliwe do wyliczenia.
  2. Get the .length własność tej tablicy.

Jeśli musisz zrobić to więcej niż raz, możesz zawinąć tę logikę w funkcję:

function size(obj, enumerablesOnly) {
    return enumerablesOnly === false ?
        Object.getOwnPropertyNames(obj).length :
        Object.keys(obj).length;
}

Jak używać tej konkretnej funkcji:

var myObj = Object.create({}, {
    getFoo: {},
    setFoo: {}
});
myObj.Foo = 12;

var myArr = [1,2,5,4,8,15];

console.log(size(myObj));        // Output : 1
console.log(size(myObj, true));  // Output : 1
console.log(size(myObj, false)); // Output : 3
console.log(size(myArr));        // Output : 6
console.log(size(myArr, true));  // Output : 6
console.log(size(myArr, false)); // Output : 7

Zobacz this Fiddle na demo.

 6
Author: John Slegers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-18 00:19:08

To działa dla mnie:

var size = Object.keys(myObj).length;
 6
Author: Giovanni Gianni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-06 09:34:40

Oto inna wersja odpowiedzi Jamesa Cogana. Zamiast przekazywać argument, po prostu prototypuj klasę obiektu i uczyń kod czystszym.

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

var x = {
    one: 1,
    two: 2,
    three: 3
};

x.size() === 3;

Jsfiddle przykład: http://jsfiddle.net/qar4j/1/

 5
Author: Sherzod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-26 23:47:45

Możesz po prostu użyć Object.keys(obj).length na dowolnym obiekcie, aby uzyskać jego długość. Obiekt.keys zwraca tablicę zawierającą wszystkie klucze obiektu (właściwości), które mogą być przydatne do znalezienia długości tego obiektu przy użyciu długości odpowiedniej tablicy. Możesz nawet napisać do tego funkcję . Weźmy creative i napisz metodę również dla niej (wraz z bardziej wygodną właściwością getter):

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

console.log(objLength({a:1, b:"summit", c:"nonsense"}));

// Works perfectly fine
var obj = new Object();
obj['fish'] = 30;
obj['nullified content'] = null;
console.log(objLength(obj));

// It also works your way, which is creating it using the Object constructor
Object.prototype.getLength = function() {
   return Object.keys(this).length;
}
console.log(obj.getLength());

// You can also write it as a method, which is more efficient as done so above

Object.defineProperty(Object.prototype, "length", {get:function(){
    return Object.keys(this).length;
}});
console.log(obj.length);

// probably the most effictive approach is done so and demonstrated above which sets a getter property called "length" for objects which returns the equivalent value of getLength(this) or this.getLength()
 4
Author: WEB_UI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-12 02:09:14

Najprostszy sposób jest taki

Object.keys(myobject).length

Gdzie myobject jest obiektem o jakiej chcesz długości

 4
Author: Mithu A Quayium,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 15:41:40

Zawsze możesz zrobić Object.getOwnPropertyNames(myObject).length, aby uzyskać taki sam wynik, jaki [].length dałby dla normalnej tablicy.

 3
Author: Pian0_M4n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-27 09:05:26
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Obiekt.wartości (myObject).długość
  2. Obiekt.wpisy (myObject).długość
  3. Obiekt.klucze (myObject).długość
 3
Author: tdjprog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 23:45:02

Poniżej Wersja odpowiedzi Jamesa Coglana w CoffeeScript dla tych, którzy porzucili prosty JavaScript:)

Object.size = (obj) ->
  size = 0
  size++ for own key of obj
  size
 2
Author: Eric Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-06 19:44:08

Własność

Object.defineProperty(Object.prototype, 'length', {
    get: function () {
        var size = 0, key;
        for (key in this)
            if (this.hasOwnProperty(key))
                size++;
        return size;
    }
});

Użyj

var o = {a: 1, b: 2, c: 3};
alert(o.length); // <-- 3
o['foo'] = 123;
alert(o.length); // <-- 4
 2
Author: Eduardo Cuomo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-06 19:10:35

Jak większość problemów JavaScript, istnieje wiele rozwiązań. Można rozszerzyć obiekt, który na dobre i na złe działa jak słownik wielu innych języków (+obywatele pierwszej klasy). Nie ma w tym nic złego, ale inną opcją jest skonstruowanie nowego obiektu, który spełni Twoje konkretne potrzeby.

function uberject(obj){
    this._count = 0;
    for(var param in obj){
        this[param] = obj[param];
        this._count++;
    }
}

uberject.prototype.getLength = function(){
    return this._count;
};

var foo = new uberject({bar:123,baz:456});
alert(foo.getLength());
 2
Author: Ron Sims II,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-19 06:27:26