Johann: Abhängigkeiten von gleichwertigen Variablen

Hallo, ich beiße gerade an folgender Crux:

var tueren = ["Eins", "Zwei", "Drei"];
var nicht_gewaehlte_tueren = tueren;
nicht_gewaehlte_tueren.splice(1, 1);
alert(tueren);

Zu meinem Erstaunen hat tueren nun ebenfalls nur die Werte "Eins" und "Drei", obwohl ich splice eigentliche auf nicht_gewaehlte_tueren angewandt habe... Warum ist das so?

Wie weise ich nicht_gewaehlte_tueren NUR DIE WERTE von tueren zu, ohne dass sich daraus weitere Abhängigkeiten ergeben?

Danke für Feedback, LG, J.

  1. Hallo Johann,

    Zu meinem Erstaunen hat tueren nun ebenfalls nur die Werte "Eins" und "Drei", obwohl ich splice eigentliche auf nicht_gewaehlte_tueren angewandt habe... Warum ist das so?

    Du verwechselst slice mit splice. Geht beides, aber splice verändert den Wert/Array.

    Gruss
    Henry

    1. Schon klar, aber warum ist tueren immer noch das Original Array von nicht_gewaehlte_tueren? Wie definiere ich nicht_gewaehlte_tueren als unabhängiges ganz und gar eigenständigstes Array, das halt zufällig die Werte von tueren übernimmt?

      1. Hallo Johann,

        aha, dann meinst du das wahrscheinlich so. (dort auf RUN klicken)

        
        <script>
        var tueren = ["Eins", "Zwei", "Drei"];
        var nicht_gewaehlte_tueren = tueren.splice(1, 1);
        </script>
        
        

        Gruss
        Henry

        1. Nachtrag,

          aha, dann meinst du das wahrscheinlich so.

          ach Blödsinn, das meinst du auch nicht, ist schon spät sry. Aber jetzt mal mit Konzentration. Was(welchen Wert/Werte) soll "nicht_gewaehlte_tueren" anzeigen?

          Gruss
          Henry

          1. nicht_gewaehlte_tueren soll ein mit splice unabhängig von tueren bearbeitbares Array sein.

        2. Hallo,

          Leider wird auch hier das Array tueren angepatzt (Output = "Eins", "Drei"). Daher: wie übernehme ich ausschließlich die Werte in nicht_gewaehlte_tueren, lösche aber sonstige Abhängigkeiten?

          1. Hallo Johann,

            Leider wird auch hier das Array tueren angepatzt (Output = "Eins", "Drei"). Daher: wie übernehme ich ausschließlich die Werte in nicht_gewaehlte_tueren, lösche aber sonstige Abhängigkeiten?

            Ja ich weiß. Vielleicht liegts daran, dass schon spät ist oder ich das "Gewünschte" nicht richtig deuten kann. Aber so wie ich es jetzt verstehe, ist wohl doch, und hier schließt sich der Kreis, Slice das sinnvollere. beachte aber die Parameter und das Array mit 0 anfängt.

            Bevor ich es weiter erkläre und vielleicht Blödsinn schreibe, schau erst mal bitte ob es das ist was du haben willst.

            Gruss
            Henry

            1. Hallo, danke für deine Hilfe 😂

              Aber mein Problem ist wohl eine Verständnisfrage, da mein Weltbild gerade ein wenig kollabiert. Ich bin bis dato davon ausgegangen dass ich mit Schemata à la

              var 1 = [x, y, z];
              var 2 = 1;
              

              das Array [x, y, z] quasi auf die Variable 2 kopiere, um dann mit beiden Variablen unabhängig voneinander operieren zu können, was so effektiv augenscheinlich nicht der Fall ist. Das heißt, wie löse ich var 1 von var 2, sodass z.B. splice() nicht auf beide zugreift, da das Original-Array nicht var 1, sondern var 2 sein sollte?

              1. Hallo Johann,

                um dann mit beiden Variablen unabhängig voneinander operieren zu können, was so effektiv augenscheinlich nicht der Fall ist.

                hmmm… Kannst du doch, oder? Nochmal ausführlicher.

                Gruss
                Henry

              2. Tach!

                Aber mein Problem ist wohl eine Verständnisfrage, da mein Weltbild gerade ein wenig kollabiert.

                Dein Problem ist nur die nicht verstandene Arbeitsweise von splice() vs. slice(). Die Methode splice() löscht im originalen Array und gibt die dort entfernten Werte zurück. Das ist ja nicht, was du möchtest. slice() hingegen liefert eine Kopie der angegebenen Werte, ohne das originale Array anzufassen. (Bei Objekten liefert es eine Kopie der Referenz, und die zeigt auf dasselbe Objekt wie das originale Array.)

                dedlfix.

  2. hallo

    var nicht_gewaehlte_tueren = tueren;

    Du kopierst lediglich eine Referenz auf einen Array. Was du aber möchtest ist aber (eventuell) ein deepClone.

    1. Hallo beatovich,

      Du kopierst lediglich eine Referenz auf einen Array. Was du aber möchtest ist aber (eventuell) ein deepClone.

      Interessanter Hinweis. Hatte ich schon mal gehört, aber weil nie Probleme nicht wirklich verinnerlicht. Vielleicht mal die Gelegenheit das erklärt zu bekommen. Als Referenz verstehe ich eine Verbindung, die abhängig ist vom Original. Verändere ich das Original, verändere ich auch die "Kopie". So sollte man meinen, die Praxis sieht aber anders aus, warum?

      <script>
      org='abcdef';
      orgcopy = org;
      
      // Bei Aufruf Originalwert ändern.
      function changeorg(){org='CHANGE';}
      </script>
      
      <button onclick="alert(org)">Zeige Original Var</button>
      <button onclick="alert(orgcopy)">Zeige Originalkopie Var</button>
      
      <button onclick="changeorg();alert('Original geändert? JA: '+org);alert('Original geändert und damit auch die Kopie? NEIN '+orgcopy);">Zeige Originalkopie Var Nach Änderung von Original</button>
      

      Gruss
      Henry

      1. hallo

        Verändere ich das Original, verändere ich auch die "Kopie". So sollte man meinen, die Praxis sieht aber anders aus, warum?

        Klar, weil du hier ein String-Literal gegen das Verhalten eines Objectes vergleichst.

        var s = new String("hello");
        s.myprop="X";
        var t = s;
        alert(t.myprop);
        
        1. Hallo beatovich,

          Klar, weil du hier ein String-Literal gegen das Verhalten eines Objectes vergleichst.

          Ok. Wenn ich aber eine Operation ausführe, verwandelt sich das intern automatisch in ein String-Objekt(glaube ich zumindest), so wie du das gerade manuell angelegt hast, und dann müsste doch eine Veränderung eintreten, was aber glücklicherweise nicht passiert.

          also Beispiel-Operation mit ausführen…

          function changeorg(){org = org.slice(0,3);org='CHANGE';}
          

          Gruss
          Henry

          1. Hallo Henry,

            ein Array und ein String sind Objekte. Objekte leben in einem Speicherbereich, den man Heap nennt, und die Zuweisung eines Objekts an eine Variable führt dazu, dass die Variable nicht mehr enthält als einen Verweis auf das Gebilde um Heap.

            Der folgende Teil ist für Strings geschrieben, gilt aber für Arrays und Objekte gleichermaßen!

            let hugo = "ABC";
            let otto = hugo;
            

            erzeugt einen String "ABC" auf dem Heap und zwei Referenzen darauf. Eine Zuweisung eines anderen Strings an hugo oder otto legt einen ANDEREN String auf den Heap und speichert eine Referenz darauf in der Variablen. String-Methoden wie substr oder slice erzeugen ebenfalls einen ANDEREN String auf dem Heap.

            Nun der Unterschied: Strings sind unveränderlich. JavaScript garantiert Dir, das ein String der einmal zugewiesen ist sich nicht mehr ändert. Diese Garantie hast Du bei Arrays und Objekten nicht. Du kannst bei Arrays einzelne Elemente ersetzen oder mit splice einen Ausschnitt verändern. Bei Objekten kannst Du Eigenschaften ändern, sogar hinzufügen. Damit änderst Du das Ding, das auf dem Heap liegt. Und wenn zwei Variablen eine Referenz auf dieses Ding halten, dann ändert sich für beide Variablen – scheinbar – der Inhalt. In Wahrheit ändert sich der Inhalt von keiner Variablen. Sondern das, worauf beide Variablen zeigen.

            Rolf

            --
            sumpsi - posui - clusi
    2. Tach!

      var nicht_gewaehlte_tueren = tueren;

      Du kopierst lediglich eine Referenz auf einen Array. Was du aber möchtest ist aber (eventuell) ein deepClone.

      Das Array hat hier lediglich simple Werte, so dass man keine umständliche DeepCopy ansetzen muss. Ein einfaches tueren.slice() reicht zum Kopieren.

      Selbst wenn die Türen Objekte wären, kann eine einfache Kopie ausreichen, besonders dann, wenn man nicht vorhat, die Türen selbst zu änderen.

      Für das Problem des OP braucht es jedoch keine komplette Kopie, denn er will ja nur Teile haben, und dafür kann man auch gleich das slice() mit begin- und end-Wert aufrufen.

      dedlfix.