Warum scheinen ihre Daten synchron zu sein?

  • Wenn ich in Javascript

     var buffer = new Array();
    buffer = AnotherArray;  
     

    ist, ist es seltsam, was ich hat gepuffert, stellte sich heraus, dass es auch AnotheArray passiert. Zum Beispiel habe ich einige Elemente im Puffer gelöscht und ich habe festgestellt, dass sie auch in AnotherArray gelöscht werden. Warum ist das so und wie kann ich es lösen?

    22 November 2011
    Newbie
5 answers
  • Ihr Code führt, wie in Anführungszeichen angegeben, absolut nicht dazu, dass das von new Array() in der ersten Zeile und AnotherArray in der nächsten Zeile erstellte Array in irgendeiner Weise in Beziehung steht. Wenn Sie einen Effekt zwischen ihnen feststellen, liegt dies in einem Code, den Sie nicht zitiert haben.

    Insbesondere erstellt Ihr Code ein Array und wirft es vollständig weg buffer verweist auf ein anderes -Ding (was nach dem Namen so aussieht, als könnte es sich um ein Array handeln). Das in der ersten Zeile erstellte Array ist jedoch verloren.

    Ich vermute, dass Sie so etwas tun:

     var buffer = new Array();
    var foo = new Array();
    buffer = foo;
    buffer.push("Testing");
    alert(foo.length); // alerts "1", not "0"
     

    In diesem Fall wird das in der ersten Zeile erstellte Array vollständig verworfen, und (in der dritten Zeile) zeigen Sie sowohl buffer als auch foo auf dasselbe Array. Es gibt nur ein Array, aber Sie haben zwei Verweise darauf. Alles, was Sie über die Referenz buffer des Arrays tun, können Sie auch sehen, wenn Sie dasselbe Array über die Referenz foo betrachten. Es gibt nur ein Array, Sie haben nur zwei Verweise darauf.

    Wenn Sie das Array kopieren möchten, finden Sie unter (ein langer Weg) unter Trennlinie.

    Wenn Sie darüber nachdenken, ist es genau das, was passiert, wenn Sie eine Referenz an eine Funktion übergeben:

     var f = new Array(); // Or better, you could use `[]` rather than `new Array()`
    f.push("one");
    bar(f);
    alert(f.length);     // alerts "2"
    
    function bar(a) {
        a.push("two");   // Here, `a` and `f` point to the **same** array
    }
     

    Dort zeigt der Alert "2" anstelle von "1", da der Code in der Funktion bar über die a -Referenz in das Array eingefügt wird Argumentliste, die auf dasselbe Array wie die Referenz f verweist.

    JavaScript verfügt über Objekttypen (auch als Referenztypen bezeichnet) und Grundelemente. Strings und Zahlen sind primitive Elemente, sie befinden sich tatsächlich im Speicher, der einer Variablen zugewiesen ist. Bei fast allen anderen Objekten handelt es sich um ein Objekt, bei dem die Variable eine Referenz auf das Objekt enthält, keine Kopie des Objekts selbst. Also:

     var a = 1;
    var b = a;
    b = 2;
    alert(a); // "1"
    alert(b); // "2"
     

    a und b haben Kopien des Primitivs Nummer 1. Aber:

     var c = {prop: "value"};
    var d = c;
    d.prop = "updated value";
    alert(c.prop); // "updated value"
     

    Dort, c und d zeigen auf das gleiche Objekt, daher sind Änderungen an dem Objekt offensichtlich, unabhängig davon, mit welcher Referenz darauf (c oder d) Sie es betrachten.

    Und natürlich:

     var e = {prop: "foo"};
    var f = {prop: "foo"};
    f.prop = "bar";
    alert(e.prop); // "foo"
     

    Da e und f auf verschiedene -Objekte, Änderungen an einem Objekt haben keine Auswirkung auf das andere.

    Um dies klar zu halten, müssen Sie sich eine -Referenz (kein Objekt) als primärer Wert. Eine Referenz ist eine beliebige Sache, mit der Sie das Objekt in einer Tabelle nachschlagen können. Während dies gilt:

     var a = 1;
     

    ... ergibt dies im Speicher:

     + ------- + 
     | a | 
     + ------- + 
     | 1 | 
     + ------- + 

    ... hier:

     var c = {prop: "value"};
     

    ... ergibt folgendes:

     + ------- + 
     | c | 
     + ------- + + --------------- + 
     | ref | ------------- & gt; | prop: "value" | 
     + ------- + + --------------- + 

    Folglich this:

     var a = 1;
    var b = a;
     

    ... ergibt:

     + ------- + 
     | a | 
     + ------- + 
     | 1 | 
     + ------- + 
     
     + ------- + 
     | b | 
     + ------- + 
     | 1 | 
     + ------- + 

    ... aber hier:

     var c = {prop: "value"};
    var d = c;
     < /pre>
    
    

    ... gibt Folgendes aus:

     + ------- + 
     | c | 
     + ------- + 
     | ref | ---- \ 
     + ------- + | 
     | 
     | + --------------- + 
     | ------ & gt; | prop: "value" | 
     | + --------------- + 
     + ------- + | 
     | d | | 
     + ------- + | 
     | ref | ---- / 
     + ------- + 

    Die Referenz ist das, was die Variablen enthalten, nicht das Objekt . Verweise sind Grundelemente, die auf Objekte zeigen.


    Was machen Sie dagegen? Die meiste Zeit ist es das, was Sie wollen, weil Sie meistens Verweise weitergeben und auf das ursprüngliche Objekt verweisen möchten. Aber manchmal möchten Sie tatsächlich ein Objekt kopieren .

    Bei Arrays ist das einfach: Verwenden Sie

    22 November 2011
    T.J. Crowder
  • buffer ist ein Verweis auf AnotherArray, einen anderen Namen für dasselbe Objekt im Speicher.

    Es ist, als würde man sich auf eine Person beziehen, die ein full verwendet Name oder Spitzname - Auf beide Arten kann auf eine Personeninstanz "zugegriffen" werden.

    22 November 2011
    Jakub Konecki
  • Dies geschieht, weil die beiden Variablen auf dasselbe Array zeigen. Um dies zu vermeiden, wenn Sie AnotherArray eine Kopie von buffer zuweisen möchten, können Sie slice() verwenden:

     var buffer = AnotherArray.slice();
     
    22 November 2011
    etuardu
  • Es passiert einiges ...

     var buffer = new Array(); // A new, empty array is created. It is
                              // accessed via buffer
    
    buffer = AnotherArray;    // Remember that new array that buffer pointed to?
                              // It's now gone, and will be garbage collected.
                              //
                              // Now buffer is a second reference to AnotherArray.
                              // Any changes to AnotherArray are now also changes
                              // to buffer. Both buffer and AnotherArray are
                              // references to a single array in memory.
     
    22 November 2011
    Larry K
  •  var buffer = new Array();
     

    Erstellt ein neues Array und bewirkt, dass buffer darauf zeigt.

     buffer = AnotherArray; 
     

    Wenn buffer auf das Array zeigt, auf das AnotherArray zeigt, zeigen buffer und AnotherArray auf dasselbe Array. Dies ist beabsichtigt, da Sie in den meisten Fällen nicht die Mühe haben müssen, ein Objekt (oder insbesondere eine Funktion) zu kopieren, was eine große Verschwendung von Speicher bedeutet.

    22 November 2011
    Esailija