964 Stimmen

Garantiert JavaScript die Reihenfolge der Objekteigenschaften?

Wenn ich ein Objekt wie dieses erstelle:

var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";

Wird das resultierende Objekt immer so aussehen?

{ prop1 : "Foo", prop2 : "Bar" }

Das heißt, werden die Eigenschaften in der gleichen Reihenfolge angezeigt, in der ich sie hinzugefügt habe?

2 Stimmen

5 Stimmen

28voto

CertainPerformance Punkte 306402

Ab ES2015 ist die Reihenfolge der Eigenschaften für bestimmte Methoden, die über Eigenschaften iterieren, garantiert. aber nicht andere . Leider sind die Methoden, bei denen eine Ordnung nicht garantiert ist, im Allgemeinen die am häufigsten verwendeten:

  • Object.keys , Object.values , Object.entries
  • for..in Schleifen
  • JSON.stringify

Aber ab ES2020 ist die Eigentumsordnung für diese bisher nicht vertrauenswürdigen Methoden se durch die Spezifikation gewährleistet sein auf dieselbe deterministische Art und Weise wie die anderen zu iterieren, und zwar aufgrund der Tatsache, dass fertig Vorschlag: Einfahrmechanik .

Genau wie bei den Methoden, die eine garantierte Iterationsreihenfolge haben (wie Reflect.ownKeys y Object.getOwnPropertyNames ), werden die zuvor nicht spezifizierten Methoden ebenfalls in der folgenden Reihenfolge durchlaufen:

  • Numerische Feldschlüssel, in aufsteigender numerischer Reihenfolge
  • Alle anderen Tasten, die keine Symboltasten sind, in Einfügereihenfolge
  • Symboltasten, in Einfügereihenfolge

Dies ist bei so gut wie jeder Umsetzung der Fall (und das schon seit vielen Jahren), aber mit dem neuen Vorschlag ist es nun offiziell.

Obwohl die aktuelle Spezifikation für in Iterationsreihenfolge " fast völlig unbestimmt Echte Motoren sind in der Regel beständiger:"

Der Mangel an Spezifität in ECMA-262 spiegelt nicht die Realität wider. In jahrelangen Diskussionen haben die Implementierer festgestellt, dass es einige Einschränkungen für das Verhalten von for-in gibt, die jeder befolgen muss, der Code im Web ausführen möchte.

Da jede Implementierung bereits vorhersehbar über Eigenschaften iteriert, kann sie in die Spezifikation aufgenommen werden, ohne die Abwärtskompatibilität zu verletzen.


Es gibt ein paar merkwürdige Fälle, die derzeit umgesetzt werden no und in solchen Fällen wird die sich daraus ergebende Reihenfolge weiterhin unbestimmt sein. Für die Eigentumsordnung zu gewährleisten :

Weder das Objekt, das iteriert wird, noch irgendetwas in seiner Prototypenkette ist ein Proxy, ein typisiertes Array, ein Modul-Namespace-Objekt oder ein exotisches Host-Objekt.

Weder das Objekt noch irgendetwas in seiner Prototypenkette ändert seinen Prototyp während der Iteration.

Weder das Objekt noch irgendetwas in seiner Prototypenkette hat eine Eigenschaft, die während der Iteration gelöscht wird.

In der Prototypenkette des Objekts wurde während der Iteration keine Eigenschaft hinzugefügt.

Keine Eigenschaft des Objekts oder irgendetwas in seiner Prototypenkette ändert seine Aufzählbarkeit während der Iteration.

Keine nicht aufzählbare Eigenschaft überschattet eine aufzählbare.

17voto

Topicus Punkte 1364

In modernen Browsern können Sie die Map Datenstruktur anstelle eines Objekts.

Entwickler mozilla > Karte

Ein Map-Objekt kann seine Elemente in Einfügereihenfolge durchlaufen...

13voto

GregRos Punkte 7896

In ES2015 schon, aber nicht so, wie Sie vielleicht denken

Die Reihenfolge der Schlüssel in einem Objekt war bis ES2015 nicht garantiert. Sie war durch die Implementierung definiert.

In ES2015 wird jedoch in war angegeben. Wie bei vielen Dingen in JavaScript wurde dies aus Kompatibilitätsgründen getan und spiegelte im Allgemeinen einen bestehenden inoffiziellen Standard unter den meisten JS-Engines wider (mit you-know-who als Ausnahme).

Die Reihenfolge ist in der Spezifikation unter der abstrakten Operation OrdinaryOwnPropertyKeys die allen Methoden der Iteration über die eigenen Schlüssel eines Objekts zugrunde liegt. Kurz gefasst lautet die Reihenfolge wie folgt:

  1. Alle ganzzahliger Index Tasten (Dinge wie "1123" , "55" , usw.) in aufsteigender numerischer Reihenfolge.

  2. Alle String-Schlüssel, die keine Integer-Indizes sind, in der Reihenfolge ihrer Erstellung (ältester-erster).

  3. Alle Symbolschlüssel, in der Reihenfolge ihrer Erstellung (älteste-erste).

Es ist dumm zu sagen, dass die Reihenfolge unzuverlässig ist - sie ist zuverlässig, sie ist nur wahrscheinlich nicht das, was Sie wollen, und moderne Browser setzen diese Reihenfolge korrekt um.

Zu den Ausnahmen gehören Methoden zur Aufzählung von geerbten Schlüsseln, wie zum Beispiel die for .. in Schleife. Die Website for .. in Schleife garantiert nicht die Reihenfolge gemäß der Spezifikation.

9voto

Drew Durham Punkte 81

Wie andere festgestellt haben, haben Sie keine Garantie für die Reihenfolge, wenn Sie über die Eigenschaften eines Objekts iterieren. Wenn Sie eine geordnete Liste von mehreren Feldern benötigen, habe ich vorgeschlagen, ein Array von Objekten zu erstellen.

var myarr = [{somfield1: 'x', somefield2: 'y'},
{somfield1: 'a', somefield2: 'b'},
{somfield1: 'i', somefield2: 'j'}];

Auf diese Weise können Sie eine normale for-Schleife verwenden und die Einfügereihenfolge beibehalten. Sie könnten dann die Array-Sortiermethode verwenden, um diese in ein neues Array zu sortieren, falls erforderlich.

5voto

kriskate Punkte 169

Ich habe das gerade auf die harte Tour herausgefunden.

Bei der Verwendung von React mit Redux wird der Zustandscontainer, dessen Schlüssel ich durchlaufen möchte, um Kinder zu erzeugen, jedes Mal aktualisiert, wenn der Speicher geändert wird (gemäß den Redux-Konzepten der Unveränderlichkeit).

Um also die Object.keys(valueFromStore) Ich habe Object.keys(valueFromStore).sort() damit ich wenigstens eine alphabetische Reihenfolge für die Schlüssel habe.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X