Ich habe folgendes JavaScript geschrieben:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['b','c']
alert(copyOfMyArray); // alerts ['b','c']
var myNumber = 5;
var copyOfMyNumber = myNumber;
copyOfMyNumber = copyOfMyNumber - 1;
alert(myNumber); // alerts 5
alert(copyOfMyNumber); // alerts 4
Dieser Code deklariert eine Variable myArray
und setzt sie auf einen Array-Wert. Es deklariert dann eine zweite Variable copyOfMyArray
und setzt sie auf myArray
. Es führt eine Operation für aus copyOfMyArray
und alarmiert dann beide myArray
und copyOfMyArray
. Wenn ich eine Operation ausführe copyOfMyArray
, scheint es irgendwie so, als würde dieselbe Operation ausgeführt myArray
.
Der Code macht dann dasselbe mit einem Zahlenwert: Er deklariert eine Variable myNumber
und setzt sie auf einen Zahlenwert. Es deklariert dann eine zweite Variable copyOfMyNumber
und setzt sie auf myNumber
. Es führt eine Operation für aus copyOfMyNumber
und alarmiert dann beide myNumber
und copyOfMyNumber
. Hier bekomme ich das erwartete Verhalten: verschiedene Werte für myNumber
und copyOfMyNumber
.
Was ist der Unterschied zwischen einem Array und einer Zahl in JavaScript, dass das Ändern eines Arrays den Wert einer Kopie des Arrays zu ändern scheint, während das Ändern einer Zahl den Wert einer Kopie der Zahl nicht ändert?
Ich vermute, dass aus irgendeinem Grund auf das Array als Referenz und die Zahl nach Wert verwiesen wird, aber warum? Wie kann ich wissen, welches Verhalten bei anderen Objekten zu erwarten ist?
quelle
myArray.slice(0);
direkt in diesem Kontext zuweisen ?Nun, die einzig mögliche Antwort - und die richtige - ist, dass Sie das Array nicht tatsächlich kopieren. Wenn du schreibst
var copyOfArray = array;
Sie weisen einer anderen Variablen einen Verweis auf dasselbe Array zu. Mit anderen Worten, sie zeigen beide auf dasselbe Objekt.
quelle
5
immer gleich sind.Alle hier haben großartige Arbeit geleistet, um zu erklären, warum dies geschieht. Ich wollte nur eine Zeile schreiben und Sie wissen lassen, wie ich das beheben konnte.
thingArray = ['first_thing', 'second_thing', 'third_thing'] function removeFirstThingAndPreserveArray(){ var copyOfThingArray = [...thingArray] copyOfThingArray.shift(); return copyOfThingArray; }
Dies verwendet die ... Spread-Syntax.
Spread-Syntaxquelle
EDIT: Zum Warum und zur Beantwortung Ihrer Frage:
Die Antwort ist, dass in JavaScript Arrays und Objekte veränderbar sind , während Zeichenfolgen und Zahlen sowie andere Grundelemente unveränderlich sind . Wenn wir eine Aufgabe erledigen wie:
copyOfMyArray ist eigentlich nur ein Verweis auf myArray, keine tatsächliche Kopie.
Ich würde diesen Artikel empfehlen: Was sind unveränderliche und veränderbare Datenstrukturen? , tiefer in das Thema zu graben.
MDN-Glossar: Veränderlich
quelle
Objekte klonen -
A
loop / array.push
erzeugt ein ähnliches Ergebnis wiearray.slice(0)
oderarray.clone()
. Alle Werte werden als Referenz übergeben. Da jedoch die meisten primitiven Datentypen unveränderlich sind , führen nachfolgende Operationen zum gewünschten Ergebnis - einem "Klon". Dies gilt natürlich nicht für Objekte und Arrays, die eine Änderung der ursprünglichen Referenz ermöglichen (es handelt sich um veränderbare Typen).Nehmen Sie das folgende Beispiel:
const originalArray = [1, 'a', false, {foor: 'bar'}] const newArray = []; originalArray.forEach((v, i) => { newArray.push(originalArray[i]); }); newArray[0] = newArray[0] + 1; newArray[1] = 'b'; newArray[2] = true; newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
Die Operationen, die auf den newArray-Indizes ausgeführt werden, führen alle zum gewünschten Ergebnis, mit Ausnahme des endgültigen (Objekts), das, da es als Referenz kopiert wird, auch das ursprünglicheArray [3] mutiert.
https://jsfiddle.net/7ajz2m6w/
Beachten Sie, dass
array.slice(0)
and array.clone()
diese Einschränkung gilt.Eine Möglichkeit, dies zu lösen, besteht darin, das Objekt während der Push-Sequenz effektiv zu klonen:
originalArray.forEach((v, i) => { const val = (typeof v === 'object') ? Object.assign({}, v) : v; newArray.push(val); });
https://jsfiddle.net/e5hmnjp0/
Prost
quelle
In JS kopiert der Operator "=" den Zeiger in den Speicherbereich des Arrays. Wenn Sie ein Array in ein anderes kopieren möchten, müssen Sie die Klonfunktion verwenden.
Denn ganze Zahlen sind anders, weil sie ein primitiver Typ sind.
S.
quelle
Mit Ausnahme der primitiven Datentypen (Zeichenfolgen und Zahlen IIRC) wird alles als Referenz kopiert.
quelle
Sie haben keine Kopien.
Sie haben mehrere Variablen, die dasselbe Array enthalten.
Ebenso haben Sie mehrere Variablen mit derselben Nummer.
Wenn Sie schreiben
copyOfMyNumber = ...
, geben Sie eine neue Zahl in die Variable ein.Das ist wie schreiben
copyOfMyArray = ...
.Wenn Sie schreiben
copyOfMyArray.splice
, ändern Sie das ursprüngliche Array .Dies ist mit Zahlen nicht möglich, da Zahlen unveränderlich sind und nicht geändert werden können.
quelle
Erstellen Sie einen Filter des ursprünglichen Arrays in der arrayCopy. Änderungen am neuen Array wirken sich also nicht auf das ursprüngliche Array aus.
var myArray = ['a', 'b', 'c']; var arrayCopy = myArray.filter(function(f){return f;}) arrayCopy.splice(0, 1); alert(myArray); // alerts ['a','b','c'] alert(arrayCopy); // alerts ['b','c']
Ich hoffe es hilft.
quelle
Das Problem bei der flachen Kopie ist, dass nicht alle Objekte geklont werden, sondern eine Referenz erhalten. So funktioniert array.slice (0) nur mit dem Literal-Array, jedoch nicht mit dem Objekt-Array. In diesem Fall ist eine Möglichkeit ..
var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}]; var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement)); console.log(clonedArray); // [{name: 'foo', id: 121}, {name: 'zoo', id: 321}] // shallow copy
quelle
Sie können abhängig von Ihren Fällen eine Fehlerbehandlung hinzufügen und eine ähnliche Funktion wie die folgende verwenden, um das Problem zu beheben. Bitte kommentieren Sie alle Fehler / Probleme / Effizienz-Ideen.
function CopyAnArray (ari1) { var mxx4 = []; for (var i=0;i<ari1.length;i++) { var nads2 = []; for (var j=0;j<ari1[0].length;j++) { nads2.push(ari1[i][j]); } mxx4.push(nads2); } return mxx4; }
quelle
Ein Array oder ein Objekt in Javascript enthält immer dieselbe Referenz, es sei denn, Sie klonen oder kopieren. Hier ist ein Beispiel:
http://plnkr.co/edit/Bqvsiddke27w9nLwYhcl?p=preview
// for showing that objects in javascript shares the same reference var obj = { "name": "a" } var arr = []; //we push the same object arr.push(obj); arr.push(obj); //if we change the value for one object arr[0].name = "b"; //the other object also changes alert(arr[1].name);
Für das Klonen von Objekten können wir .clone () in jquery und angle.copy () verwenden. Diese Funktionen erstellen ein neues Objekt mit einer anderen Referenz. Wenn Sie mehr Funktionen dafür kennen, sagen Sie mir bitte, danke!
quelle