Anzahl der Elemente in einem Javascript-Objekt

103

Gibt es eine Möglichkeit, (von irgendwoher) die Anzahl der Elemente in einem Javascript-Objekt zu ermitteln? (dh zeitkonstante Komplexität).

Ich kann keine Eigenschaft oder Methode finden, die diese Informationen abruft. Bisher kann ich nur daran denken, die gesamte Sammlung zu iterieren, aber das ist lineare Zeit.
Es ist seltsam, dass es keinen direkten Zugriff auf die Größe des Objekts gibt.

EDIT:
Ich spreche über das ObjectObjekt (nicht Objekte im Allgemeinen):

var obj = new Object ;
GetFree
quelle
5
Bereits hier beantwortet stackoverflow.com/questions/126100/... Object.keys (obj) .length
spats

Antworten:

155

Obwohl JS-Implementierungen einen solchen Wert möglicherweise intern verfolgen, gibt es keinen Standardweg, um ihn abzurufen.

In der Vergangenheit hat Mozillas Javascript-Variante den Nicht-Standard__count__ verfügbar gemacht, wurde jedoch mit Version 1.8.5 entfernt.

Bei Cross-Browser-Skripten müssen Sie die Eigenschaften nicht explizit durchlaufen und Folgendes überprüfen hasOwnProperty():

function countProperties(obj) {
    var count = 0;

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

    return count;
}

Bei ECMAScript 5-fähigen Implementierungen kann dies auch als (Kudos to Avi Flax ) geschrieben werden.

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

Denken Sie daran, dass Sie auch Eigenschaften vermissen, die nicht aufzählbar sind (z. B. die eines Arrays length).

Wenn Sie ein Framework wie jQuery, Prototype, Mootools oder $ Whatever-the-Recent-Hype verwenden, prüfen Sie, ob diese über eine eigene Sammlungs-API verfügen. Dies ist möglicherweise eine bessere Lösung für Ihr Problem als die Verwendung nativer JS-Objekte.

Christoph
quelle
11
Verdammt, ich vergesse immer hasOwnProperty. Zu viel Zeit im .NET-Land, sage ich Ihnen. +1
Annakata
2
jQuery verwendet ein Objekt für seine Sammlungen, die es aus Abfragen erhält, und macht diesen Wert mit einer length-Eigenschaft verfügbar.
Nosredna
6
Firefox4 __count__ist weg :(
Timo Huovinen
1
Gibt es eine Möglichkeit, dies ohne ein For-In zu tun? Ich bin in der gleichen Art von Bindung, aber ich möchte, dass es JSLint passiert, wenn es überhaupt möglich ist.
Straßenlaterne
1
Warum brauchen wir hasOwnProperty()?
Schweizer
99

Dazu in jeder ES5-kompatiblen Umgebung

Object.keys(obj).length

( Browserunterstützung von hier )
(Doc on Object.keys hier , enthält eine Methode, die Sie Nicht-ECMA5-Browsern hinzufügen können.)

ZelkiN
quelle
2
Dies ist nicht die richtige Frage, um diese Antwort zu geben. Damit nehmen Sie alle Schlüssel des Objekts, fügen sie in ein neu erstelltes Array ein und rufen dann die Länge-Eigenschaft aus diesem neuen Array ab.
GetFree
11
Es ist möglicherweise nicht das programmatisch effizienteste, aber es ist das effizienteste für Entwickler.
Superluminary
9

Wenn Sie jQuery bereits in Ihrem Build verwenden, gehen Sie wie folgt vor:

$(yourObject).length

Es funktioniert gut für mich bei Objekten, und ich hatte jQuery bereits als Abhängigkeit.

IndelibleHeff
quelle
5
Seltsam ... das funktioniert bei mir nicht. Ich bekomme immer 1. ZelkiNs Antwort funktioniert für mich.
Mike Nagetier
3
Dieser Code gibt immer 1 zurück. Nur 1 Objekt. Es zählt keine Elemente darin
BeRocket
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);
kennebec
quelle
2

AFAIK, es gibt keine Möglichkeit, dies zuverlässig zu tun, es sei denn, Sie wechseln zu einem Array. Was ehrlich gesagt nicht seltsam erscheint - es scheint mir ziemlich einfach zu sein, dass Arrays zählbar sind und Objekte nicht.

Wahrscheinlich ist der nächste, den Sie bekommen, so etwas

// 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

Dies schafft jedoch Probleme oder zumindest Fragen. Alle vom Benutzer erstellten Eigenschaften werden gezählt, einschließlich der Funktion _length selbst! In diesem einfachen Beispiel können Sie dies vermeiden, indem Sie nur eine normale Funktion verwenden. Dies bedeutet jedoch nicht, dass Sie andere Skripte daran hindern können, dies zu tun. also, was machst du? Funktionseigenschaften ignorieren?

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

Am Ende denke ich, Sie sollten wahrscheinlich die Idee aufgeben, Ihre Objekte zählbar zu machen und einen anderen Weg finden, um das zu tun, was Sie gerade tun.

Peter Bailey
quelle
8
GEFAHR WIRD ROBINSON! Do NOT Proto gegen Objekt! Alles stammt von Object ab. Sie werden die Client-Verarbeitung auf diese Weise lahm legen, wenn Sie eine beträchtliche Menge an JS-Arbeit erledigen.
Annakata
5
Äh ... hast du nicht den Teil gelesen, in dem ich in einem Kommentar "Monkey Patching absichtlich, um einen Punkt zu machen" geschrieben habe - komm schon, ich habe das absichtlich gemacht, damit die Leute nicht ein bisschen darüber nachdenken. Außerdem, obwohl ich das Patchen von Affen nicht befürworte, verstehen Sie falsch, wie die Prototypenkette in Javascript funktioniert, wenn Sie glauben, dass dies zu Leistungsproblemen führen würde video.yahoo.com/watch/111585/1027823
Peter Bailey
Also ... das ist ein Do oder ein Don't?
OscarRyz
In "Javascript: The Good Parts" prototypisiert er Objekte mit einer "create ()" - Methode. Ich glaube, das ist das endgültige Buch über Javascript.
Chris Dutrow
1

Das Konzept von Zahl / Länge / Dimensionalität ist für ein Objekt nicht wirklich sinnvoll, und wenn Sie es benötigen, möchten Sie mir wirklich ein Array.

Edit: Hat mich darauf hingewiesen, dass du dafür ein O (1) willst. Nach meinem besten Wissen gibt es leider keinen solchen Weg.

Annakata
quelle
Er schlug vor, sich selbst zu wiederholen, was diese Lösung ist. Er brauchte einen O (1) Weg, um dies zu erreichen ...
Thomas Hansen
Du liegst richtig. Sollte wirklich Fragen gründlicher lesen.
Annakata
Tatsächlich sind Objekte einer Karte in JS am nächsten. Karten haben Länge.
Cristian Vrabie