Werden Objekte in einer tiefen oder flachen Javascript-Kopie in ein Array verschoben?

73

Ziemlich selbstverständliche Frage ... Wenn Sie .push () für ein Array in Javascript verwenden, wird dem Objekt unabhängig vom Typ ein Zeiger (flach) oder das tatsächliche Objekt (tief) in das Array verschoben .

Travis J.
quelle

Antworten:

136

Es hängt davon ab, was Sie vorantreiben. Objekte und Arrays werden als Zeiger auf das ursprüngliche Objekt verschoben. Eingebaute primitive Typen wie Zahlen oder Boolesche Werte werden als Kopie übertragen. Da Objekte in keiner Weise kopiert werden, gibt es keine tiefe oder flache Kopie für sie.

Hier ist ein funktionierender Ausschnitt, der es zeigt:

var array = [];
var x = 4;
let y = {name: "test", type: "data", data: "2-27-2009"};

// primitive value pushes a copy of the value 4
array.push(x);                // push value of 4
x = 5;                        // change x to 5
console.log(array[0]);        // array still contains 4 because it's a copy

// object reference pushes a reference
array.push(y);                // put object y reference into the array
y.name = "foo";               // change y.name property
console.log(array[1].name);   // logs changed value "foo" because it's a reference    

// object reference pushes a reference but object can still be referred to even though original variable is no longer within scope
if (true) {
    let z = {name: "test", type: "data", data: "2-28-2019"};
    array.push(z);
}

console.log(array[2].name);   // log shows value "test" since the pointer reference via the array is still within scope
jfriend00
quelle
45

jfriend00 ist hier genau richtig, aber eine kleine Klarstellung: Das bedeutet nicht, dass Sie nicht ändern können, auf was Ihre Variable zeigt. Das heißt, Sie yverweisen zunächst auf eine Variable, die Sie in das Array eingefügt haben. Anschließend können Sie die benannte Variable nehmen y, sie von dem Objekt trennen, das sich jetzt im Array befindet, und eine völlig andere Verbindung herstellen y(dh sie referenzieren lassen ), ohne das Objekt zu ändern das wird jetzt nur vom Array referenziert .

http://jsfiddle.net/rufwork/5cNQr/6/

var array = [];
var x = 4;
var y = {name: "test", type: "data", data: "2-27-2009"};

// 1.) pushes a copy
array.push(x);
x = 5;
document.write(array[0] + "<br>");    // alerts 4 because it's a copy

// 2.) pushes a reference
array.push(y);
y.name = "foo";

// 3.) Disconnects y and points it at a new object
y = {}; 
y.name = 'bar';
document.write(array[1].name + ' :: ' + y.name + "<br>");   
// alerts "foo :: bar" because y was a reference, but then 
// the reference was moved to a new object while the 
// reference in the array stayed the same (referencing the 
// original object)

// 4.) Uses y's original reference, stored in the array,
// to access the old object.
array[1].name = 'foobar';
document.write(array[1].name + "<br>");
// alerts "foobar" because you used the array to point to 
// the object that was initially in y.
Ruffin
quelle
2
Interessanter Punkt newzum "Trennen" der Objektreferenz.
Travis J
2
Erklärung ablehnen? Es ist schwierig, das Problem zu beheben, wenn Sie mich nicht wissen lassen, was es war.
Ruffin
Warum mich anpingen? Ich habe dies vor langer Zeit positiv bewertet und Ihre Antwort hat mir gefallen. Hier ist ein Bildschirm der Abstimmung: i.imgur.com/AnDt98c.png
Travis J
1
Sorry @Travis - Kollateralschaden für SO, da ich keine andere Möglichkeit habe, mit dem kürzlich anonymen Downvoter zu kommunizieren, der in den letzten ein oder zwei Wochen vorbeigekommen ist. Ich habe nicht erwartet, dass es von dir kommt, insb. mit Ihrem positiven Kommentar. Entschuldigen Sie den unglücklichen Spam auf Ihrem Weg und vielen Dank, dass Sie Ihre Frage im Auge behalten haben!
Ruffin
1
Das war eigentlich ein Missverständnis von meiner Seite. Mein Fehler. Ihr Kommentar wurde in meinen Benachrichtigungen angezeigt und ich dachte, er sei an mich gerichtet, weil ich nicht wusste, dass alle Kommentare als OP als Benachrichtigungen angezeigt werden.
Travis J