Knotenknut: Wie füge ich einem Objekt eine Eigenschaft an einer BESTIMMTEN Position zu?

Hallo,

kurze Frage...

wie füge ich einem Objekt eine Eigenschaft an einer BESTIMMTEN Position zu?

Also ein wenig sowas wie splice() für Objekte...

Muss ich dazu über die Elemente iterieren, oder gibt es für Objekte eine Methode, die eine Eigenschaft direkt anspricht?

BSP:

let objekt1 = {property1: 'value1', property3: 'value3'};
let hinzukommt = {property2: 'value2'};

// füge 'hinzukommt' NACH property1, bzw. ZWISCHEN property1 und property3 ein.

Danke für faires Gedankengut, Knut.

  1. Hallo,

    let objekt1 = {property1: 'value1', property3: 'value3'};
    objekt1.property2 = 'value2';
    

    aber wozu benötigst du die Reihenfolge?

    Gruß
    Jürgen

  2. Hey,

    Bei Objekten, gibt es gar nicht unbedingt eine spezielle Position oder Reihenfolge, die werden in der Console zum Beispiel auch nach der Eigenschaften Alphabetisch geordnet. Also ein einfaches:

    let objekt1 = {property1: 'value1', property3: 'value3'};
    objekt1.property2  = 'value2';
    

    genügt eigentlich und sollte deinen Erwartungen entsprechen.

    Gruß
    Jo

    1. Hey,

      Bei Objekten, gibt es gar nicht unbedingt eine spezielle Position oder Reihenfolge, die werden in der Console zum Beispiel auch nach der Eigenschaften Alphabetisch geordnet.

      Ich muss mich korrigieren: Ein Versuch zeigt bei mir in der Chrome Konsole erst in dem arr1 die geordneten Eigenschaften an.

      Die Eigenschaften werden also wie bei array.push() einfach hinten angefügt.

      Also wäre JürgenB's Frage berechtigt ob die Reihenfolge eine Rolle spielt?

      Gruß
      Jo

  3. let objekt1 = {property1: 'value1', property3: 'value3'};
    let hinzukommt = {property2: 'value2'};
    
    // füge 'hinzukommt' NACH property1, bzw. ZWISCHEN property1 und property3 ein.
    

    Das ist ein Array, also ein ganz spezielles Objekt. Mein spontaner Gedanke: Du kreierst ein neues Array, kopierst die vorangehenden Positionen, fügst die neue ein und kopierst den Rest.

    Linuchs

    P.S. Eure Rechtschreibkorrektur ist geil. Hat das Wort kreirst als falsch markiert. Alle Achtung.

    1. let objekt1 = {property1: 'value1', property3: 'value3'};
      let hinzukommt = {property2: 'value2'};
      
      // füge 'hinzukommt' NACH property1, bzw. ZWISCHEN property1 und property3 ein.
      

      Das ist ein Array, also ein ganz spezielles Objekt. Mein spontaner Gedanke: Du kreierst ein neues Array, kopierst die vorangehenden Positionen, fügst die neue ein und kopierst den Rest.

      Das ist ein Objekt.

      Das arr1 = [] ist ein Array.

      Gruß
      Jo

    2. Hallo,

      let objekt1 = {property1: 'value1', property3: 'value3'};
      let hinzukommt = {property2: 'value2'};
      
      // füge 'hinzukommt' NACH property1, bzw. ZWISCHEN property1 und property3 ein.
      

      Das ist ein Array, also ein ganz spezielles Objekt.

      nein. {…} ist ein Object und […] ein Array.

      Mein spontaner Gedanke: Du kreierst ein neues Array, kopierst die vorangehenden Positionen, fügst die neue ein und kopierst den Rest.

      Und was willst du damit erreichen?

      Gruß
      Jürgen

    3. Hallo,

      P.S. Eure Rechtschreibkorrektur ist geil. Hat das Wort kreirst als falsch markiert. Alle Achtung.

      es kommt ja auch von "kreieren" (mit "ie"), also ist die richtige Form "kreierst".

      Viele Grüße Matti

    4. Hallo Linuchs,

      P.S. Eure Rechtschreibkorrektur ist geil. Hat das Wort kreirst als falsch markiert. Alle Achtung.

      Nicht unsere. Die des Browsers.

      Bis demnächst
      Matthias

      --
      Pantoffeltierchen haben keine Hobbys.
  4. Hallo Knut

    kurze Frage...

    wie füge ich einem Objekt eine Eigenschaft an einer BESTIMMTEN Position zu?

    Kurze Antwort:

    Gar nicht.


    Etwas längere Antwort:

    Objekteigenschaften haben keine definierte Reihenfolge. Das heißt insbesondere, dass du dich nicht darauf verlassen kannst, dass bei der Iteration über die Eigenschaften eines Objekts die Reihenfolge eingehalten wird, in der die Eigenschaften angelegt wurden. Vielleicht wird sie das, vielleicht auch nicht.

    Wenn du Strings als Schlüssel verwenden willst, aber die Reihenfolge der Einträge eine Rolle spielt, dann sind plane Objekte nicht die richtige Datenstruktur für dich. Besser geeignet für diesen Anwendungsfall sind Maps. Bei einer Map werden die Einträge grundsätzlich in der Reihenfolge gespeichert, in der sie hinzugefügt wurden.

    // Create a map
    
    const map = new Map([
        ['key 1', 'value 1'],
        ['key 2', 'value 2']
    ]);
    

    Möchtest du an einer bestimmten Stelle einen Eintrag hinzufügen, kannst du dir die Einträge deiner Map in ein Array kopieren, die Liste aktualisieren und mit dem Ergebnis wieder eine Map erzeugen. Bei Maps handelt es sich um iterierbare Objekte und es werden standardmäßig die Einträge als Array mit zwei Elementen ausgegeben, so wie sie dem Konstruktor in dem Beispiel oben übergeben wurden.

    Du kannst zum Beispiel die Methode Array.from mit einer Map aufrufen.

    Der Wiki-Artikel, den ich zum Thema Maps geschrieben habe, ist leider noch nicht ganz fertig, aber eigentlich solltest du dort alle nötigen Informationen finden. Eine kürzere Übersicht zu Maps findest du in diesem Forumsbeitrag. Dort sind ebenfalls alle Methoden mit Kurzbeschreibung und entsprechendem Beispiel aufgeführt.

    Viele Grüße,

    Orlok

    1. Danke für eure Antworten! 😀

      ...Ähnliches habe ich bereits befürchtet.

      Prizipiell will ich das Objekt via JSON als Zeichenkette an den Server schicken und dort wieder dekodieren…

      @Orlok Vielen Dank für die sehr ausführliche Darstellung!

      Gehe ich recht in der Annahme, dass ich, wenn ich eine geordnete Reihenfolge der Elemente haben will, um ein Array nicht herumkomme?

      ...da erscheint mir der Umweg über eine Map ein wenig als Fleißaufgabe, oder sehe ich das falsch? Wäre da nicht ein Objekt-Array naheliegender?

      LG, Knut

      1. Hallo Knotenknut,

        wenn Du die JSON-Repräsentation eines Objekts erzeugen willst, hilft Dir ein Array nicht. Daraus entsteht die JSON-Repräsentation eines Arrays.

        Wenn Du eine geordnete Liste von Key-Value Paaren in JSON-Objektnotation haben willst, hilft Dir aber auch eine Map nichts. Zumindest nicht out-of-the-box in Chrome, der serialisiert keine Maps zu JSON.

        let a = new Map();
        a.set("foo", 1);
        a.set("bar", 2);
        console.log(JSON.stringify(a));
        // -> {}
        

        Meine persönliche Befürchtung wäre: um eine JSON-Darstellung eines Objekts mit einer definierten Reihenfolge der Properties zu erhalten, musst Du selbst Hand anlegen.

        Die Frage, die sich dann stellt, ist natürlich diese: Wozu brauchst Du beim Empfänger diese definierte Reihenfolge? Wenn der Empfänger den JSON-String deserialisiert, bekommt er wieder ein Objekt. Die verwendete Serversprache muss dann auch erstmal eine Reihenfolge der Properties garantieren.

        Deswegen: um eine definierte Reihenfolge von Key-Value Paaren zu erhalten - ja, da ist wohl ein Array von Objekten die sachlich richtige Lösung (oder ein Array von Key+Value Arrays).

        So - klare Key-Value Objekte, aber längliche Serialisierung:

        let a = [ { key: "foo&bar", value: 1 }, { key: "hui", value: 2 } ];
        // JSON.stringify(a) -> "[{"key":"foo&bar","value":1},{"key":"hui","value":2}]"
        

        oder so - das funktioniert immer:

        let a = [ [ "foo&bar", 1 ], [ "hui", 2 ] ];
        // JSON.stringify(a) -> "[["foo&bar",1],["hui",2]]"
        

        oder so - Key-Value Paare als Objekte mit genau einer Eigenschaft:

        let b = [ { "foo&bar": 1 }, { "hui": 2 } ];
        // JSON.stringify(b) -> "[{"foo&bar":1},{"hui":2}]"
        

        Ob letzteres mit deiner serverseitigen Sprache funktioniert, musst Du schauen. Nicht jede Sprache lässt beliebige Zeichen in Namen für Properties zu.

        Rolf

        --
        sumpsi - posui - clusi
        1. Hallo Rolf,

          wobei die Frage bleibt: Warum ist bei einem Objekt die Reihenfolge von Interesse? Der Zugriff geht doch über einen Key und nicht über einen Index.

          Gruß
          Jürgen

          1. Tach!

            wobei die Frage bleibt: Warum ist bei einem Objekt die Reihenfolge von Interesse? Der Zugriff geht doch über einen Key und nicht über einen Index.

            Ich würde das als eine falsch herum gestellte Frage ansehen. Vielmehr wäre von Interesse, was der Anwendungsfall ist, und als Folge dessen, was die dazu passende Datenstruktur ist. Die Reihenfolge ist nicht aufgrund der Objekteigenheiten irrelevant, sondern ein Objekt ist aufgrund der nicht vorhandenen Garantie keine Lösung für den Wunsch nach Reihenfolge.

            Gegebenenfalls wäre jedoch die Frage zu klären, ob diese Reihenfolge wirklich für den Anwendungsfall benötigt wird.

            dedlfix.

            1. hallo

              Tach!

              wobei die Frage bleibt: Warum ist bei einem Objekt die Reihenfolge von Interesse? Der Zugriff geht doch über einen Key und nicht über einen Index.

              Ich würde das als eine falsch herum gestellte Frage ansehen. Vielmehr wäre von Interesse, was der Anwendungsfall ist, und als Folge dessen, was die dazu passende Datenstruktur ist. Die Reihenfolge ist nicht aufgrund der Objekteigenheiten irrelevant, sondern ein Objekt ist aufgrund der nicht vorhandenen Garantie keine Lösung für den Wunsch nach Reihenfolge.

              Gegebenenfalls wäre jedoch die Frage zu klären, ob diese Reihenfolge wirklich für den Anwendungsfall benötigt wird.

              Beispiel Objekt über console.log ausgeben. Die Objekt-Eigenschaften werden alphabetisch sortiert gelistet.

              Hier ist es der User, der einen Überblick braucht. Das sei nur als eine sehr alltägliche Anwendung erwähnt.

              1. Hallo Beat,

                aber in der Konsole kommt die Sortierung aus der Anzeigefunktion, nicht aus der Datenstruktur. Dedlfix hat schon Recht und Knotenknut sollte sich mal dazu äußern, warum er die Reihenfolge benötigt.

                Gruß
                Jürgen

                1. hallo

                  aber in der Konsole kommt die Sortierung aus der Anzeigefunktion, nicht aus der Datenstruktur. Dedlfix hat schon Recht und Knotenknut sollte sich mal dazu äußern, warum er die Reihenfolge benötigt.

                  Reicht es nicht zu wissen, dass er sie benötigt? Dass man unter Umständen Objekte in einer bestimmten Sortierung/Ordnung präsentieren will, habe ich dir soeben demonstriert.

                  1. Hallo Beat,

                    womit wir bei deflfix‘s Antwort sind.

                    Gruß
                    Jürgen

                    1. hallo

                      Hallo Beat,

                      womit wir bei deflfix‘s Antwort sind.

                      Wenn's ein Objekt sein soll, brauchen wir halt eine separate Eigenschaft: propOrder:[]. Wann immer wir eine Eigenschaft dann anfügen, führen wir wir ein propOrder.push(propName) durch.

                  2. Wobei eine alphabetische oder numerische Sortierung plattformunabhängig jederzeit reproduzierbar ist. Wie auch immer, wenn Daten serialisiert werden, wird ja auch die Reihenfolge eingeforen. Nur JSON kann das eben mal gerade nicht. Es sei denn ich baue mir meinen eigenen JSON Serializer dem ich die Reihenfolge übergebe (hab ich auch schon gemacht).

                    MfG

          2. hi @JürgenB

            wobei die Frage bleibt: Warum ist bei einem Objekt die Reihenfolge von Interesse?

            Occh da gibt es schon Erfordernisse und Begehrlichkeiten. Zum Beispiel wenn die Eigenschaften per Webfomular zu bearbeiten sind, macht sich eine bestimmte Reihenfolge immer ganz gut.

            Von wegen UX und so. MfG

            1. Hallo,

              dann ist aber möglicherweise ein Object in Javascript nicht die optimale Datenstruktur.

              Gruß
              Jürgen

              1. Hallo,

                dann ist aber möglicherweise ein Object in Javascript nicht die optimale Datenstruktur.

                So? Was wäre denn eine optimale Datenstruktur?

                Abgesehen davon wird man doch nicht seine internen Datenstrukturen ändern wollen wenn der Kunde im Backend eine bestimmte Reihenfolge haben will. Machst Du das etwa?

                MfG

                1. Hallo Rolf,

                  die Antwort weis nur Knotenknut.

                  Gruß
                  Jürgen

        2. hi @Rolf B

          Die Frage, die sich dann stellt, ist natürlich diese: Wozu brauchst Du beim Empfänger diese definierte Reihenfolge? Wenn der Empfänger den JSON-String deserialisiert, bekommt er wieder ein Objekt. Die verwendete Serversprache muss dann auch erstmal eine Reihenfolge der Properties garantieren.

          Nein, nicht die Serversprache. Vielmehr muss eine Reihenfolge, falls gewünscht, bereits beim Sender festgelegt und natürlich auch zum Empfänger transportiert werden.

          ZB. so:

          obj = {
            foo: '',
            bar: '',
            baz: '';
            atts: ['bar','baz','foo'] // Reihenfolge festlegen
          };
          

          Und wie eine solche Datenstruktur serialisiert wird, ist völlig Wurscht. Das kann JSON sein, muss aber nicht.

          Wobei, ganz Wurscht ist es nicht, denn es gibt Enctypes, die transportieren auch die Reihenfolge, z.B. application/x-www-form-urlencoded

          bar=;baz=foo=;
          

          MfG

          1. Hallo pl,

            atts: ['bar','baz','foo']

            das ist eine von mehreren Lösungen, die das instabile Detail "JavaScript speichert Properties in Zugangsreihenfolge" umgehen. Zwei andere stehen in meinem Posting.

            Der Ausgangspunkt meines Hinweises, dass die Serversprache mitspielen muss, bezog sich aber darauf, dass man es am Client schafft, ein JSON-Serialisat[1] eines Objekts zu erzeugen, in dem die Eigenschaften die gewünschte Reihenfolge haben, und war letztlich als weiteres Argument gedacht gegen die Idee, für eine reihenfolgestabile Übertragung die JSON-Repräsentation „Objekt“ zu verwenden.

            Für Knotenknut stellt sich jetzt nur die Abwägung, welche Datenstruktur er in JS verwendet. Genügt ein Array von Eigenschaftsobjekten oder ist das zu langsam für den laufenden Betrieb? Wenn tatsächlich Eigenschaften mittendrin einsortiert werden müssen, dann hilft auch die Map nichts - die unterstützt das nämlich nicht. Dann hilft nur ein Objekt, das um deine Indexliste erweitert ist, oder man ersetzt das Objekt gleich durch ein Array von Eigenschaften. Und darin splice-t man die neuen Eigenschaften an die passende Position. Das sollte man dann auch sinnvollerweise in einer eigenen Klasse kapseln - und darüber jammern, dass man in JS keine Operatoren überladen kann.

            Rolf

            --
            sumpsi - posui - clusi

            1. Hm. Gibt's das Wort? ↩︎

            1. Natürlich ist auch in einen JSON-Serialisat die Reihenfolge eingefroren. Die Frage ist nur, wie man sie definiert einfriert und matschfrei wieder auftaut.

              MfG

      2. hi

        Gehe ich recht in der Annahme, dass ich, wenn ich eine geordnete Reihenfolge der Elemente haben will, um ein Array nicht herumkomme?

        So isses.

        ...da erscheint mir der Umweg über eine Map ein wenig als Fleißaufgabe, oder sehe ich das falsch? Wäre da nicht ein Objekt-Array naheliegender?

        Überlege eine zweckmäßige Datenstruktur. Zum Beispiel ein Array mit Objekten: [{},{}..] da steht die Reihenfolge fest und der Zugriff auf die einzelnen Objekte erfolgt über den Index 0..n-1.

        Und selbstverständlich kannst Du zu jedem Objekt auch ein Array für die Eigenschaften anlegen womit deren Reihenfolge manifestiert ist.

        MfG