Kopieren array als Wert
Beim kopieren eines Arrays in JavaScript ein array:
var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d'); //Now, arr1 = ['a','b','c','d']
Erkannte ich, dass arr2
bezieht sich auf das gleiche array wie arr1
, anstatt ein neues, eigenständiges array. Wie kann ich kopieren, das array um zwei unabhängige arrays?
Es sieht aus wie aktuell in Chrome 53 und Firefox 48 wir haben Coole performance für
jsben.ch/#/wQ9RU <= dieser benchmark gibt einen überblick über die verschiedenen Möglichkeiten zum kopieren eines Arrays
jsperf.com/flat-array-copy
Für dieses array (enthält primitive strings) können Sie
Es 2017, so dass Sie vielleicht zu prüfen, mit ES6-features:
slice
und splice
Operationen und neue spread-operator und Array.from
viel langsameren Umsetzung. Look at perfjs.fnfojsben.ch/#/wQ9RU <= dieser benchmark gibt einen überblick über die verschiedenen Möglichkeiten zum kopieren eines Arrays
jsperf.com/flat-array-copy
Für dieses array (enthält primitive strings) können Sie
var arr2 = arr1.splice();
zu tief kopieren, aber diese Technik wird nicht funktionieren, wenn die Elemente in deinem array enthalten wörtliche Strukturen (d.h. []
oder {}
) oder Prototyp-Objekte (d.h. function () {}
, new
, etc). Siehe meine Antwort unten für weitere Lösungen.Es 2017, so dass Sie vielleicht zu prüfen, mit ES6-features:
let arr2 = [...arr1];
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...InformationsquelleAutor Dan | 2011-09-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwenden:
Grundsätzlich die
slice()
Betrieb Klone der array und liefert eine Referenz auf ein neues array. Beachten Sie auch, dass:Referenzen, strings und zahlen (und nicht das eigentliche Objekt),
slice()
Kopien Objekt-Referenzen in das neue array. Sowohl die ursprünglichen und die neuen array auf das gleiche Objekt beziehen. Wenn ein referenziertes Objekt verändert, werden die änderungen sichtbar sind, um sowohl die neuen und ursprünglichen arrays.Primitiven wie strings und zahlen sind unveränderlich, so dass änderungen an der Zeichenfolge oder Zahl sind unmöglich.
Auch wenn dies bereits eine Tonne von upvotes, die es verdient, ein anderer, weil er richtig beschreibt, verweist in JS, welche Art von selten, leider.
Sie würde hinzufügen eine ganze Bibliothek einfach für die Lesbarkeit? Wirklich? Ich würde nur einen Kommentar hinzufügen, wenn ich das sorgen für die Lesbarkeit. Siehe: var newArray = oldArray.slice(); //Clone oldArray zu newArray
Ich bekomme, dass sicher. Aber die Beantwortung einer spezifischen engineering-problem, indem eine ganze Bibliothek meiner Meinung nach nicht hilfreich, es ist design aufblasen. Ich sehe Entwickler, die eine Menge, und dann Sie am Ende mit einem Projekt, die einen gesamten Rahmen ersetzen zu müssen, schreiben Sie eine einzige Funktion. Nur meine M. O., obwohl.
Lektion gelernt: nicht zu verwechseln
.slice()
mit.splice()
, gibt Sie ein leeres array. Großen Unterschied.InformationsquelleAutor Saket
In Javascript, deep-copy-Techniken abhängen, die Elemente in einem array. Lassen Sie uns dort anfangen.
Drei Arten von Elementen
Elemente: Literale Werte, Literale, Strukturen, oder Prototypen.
Aus diesen Elementen können wir drei Typen von arrays.
Tiefe Kopie-Techniken hängen von der drei array-Typen
Basierend auf die Arten von Elementen in dem array, können wir verwenden verschiedene Techniken, um tief zu kopieren.
Array-literal-Werte (Typ1)
Die
[...myArray]
,myArray.splice(0)
,myArray.slice()
, undmyArray.concat()
Techniken können verwendet werden, um Tiefe Kopie-arrays mit literal-Werten (boolean, number und string) ist; wobei die Spread-operator[...myArray]
hat die beste Leistung (https://measurethat.net/Benchmarks/Show/4281/0/spread-array-performance-vs-slice-splice-concat).Array-literal-Werte (Typ1) und literal-Strukturen (Typ2)
Die
JSON.parse(JSON.stringify(myArray))
Technik kann verwendet werden, um Tiefe Kopie Literale Werte (boolean, number, string) und wörtliche Strukturen (array, Objekt), aber nicht Prototyp-Objekte.Alle arrays (type1, type2, type3)
Die jQuery -
$.extend(myArray)
Technik kann verwendet werden, um deep-copy alle array-Typen. Bibliotheken wie Unterstreichen und Lo-dash bieten ähnliche deep-copy-Funktionen, um jQuery$.extend()
, haben aber eine geringere Leistung. Noch erstaunlicher ist, dass$.extend()
hat eine höhere Leistung als dieJSON.parse(JSON.stringify(myArray))
Technik http://jsperf.com/js-deep-copy/15.Und für diejenigen Entwickler, die sich scheuen, von third-party-Bibliotheken (wie jQuery), können Sie mit der folgenden benutzerdefinierten Funktion; die hat eine höhere Leistung als das $.verlängern tief und kopiert alle arrays.
So die Frage zu beantworten...
Frage
Antwort
Weil
arr1
ist ein array von literal-Werten (boolean, eine Zahl oder ein string), können Sie eine beliebige Tiefe Kopie Technik, die oben diskutiert wird, wo der spread-operator...
hat die höchste Leistung.arr1
. Es ist sehr selten, dass das der Fall sein wird. Mitsplice
vernichtetarr1
, so dass es nicht eine Kopie an alle. MitJSON
fehl, wenn einer der Werte im array-Funktionen oder Prototypen (wie einDate
).Mit splice ist eine partielle Lösung. Es wird scheitern, unter weit mehr Fälle als JSON. Splice erzeugt eine Tiefe Kopie des strings und zahlen, wenn es sich bewegt-Werte - nie gesagt, es gibt eine Kopie.
Warum splice(0)? Sollte es nicht slice() ? Ich denke, es ist eigentlich nicht zu ändern, original-array die splice hat. @JamesMontagne
splice erstellen, Zeiger auf die Elemente im ursprünglichen array (flache Kopie). splice(0) neuen Speicher (Tiefe Kopie) für die Elemente im array die zahlen oder strings, und erstellen Hinweise für alle anderen element-Typen (flache Kopie). Indem ein Startwert von null auf die splice-Funktion-Methode, es wird nicht Spleißen Sie keine Elemente aus dem ursprünglichen array an, und daher nicht zu modifizieren.
Eigentlich gibt es nur eine Art von array: ein array von "somethings". Es gibt keinen Unterschied zwischen
[0,"1",{2:3},function random() {return 4;}, [[5,6,7],[8,9,10],[11,12,13]]]
und jedes andere array.InformationsquelleAutor tfmontague
Können Sie array-spreads
...
zum kopieren von arrays.const itemsCopy = [...items];
Auch wenn Sie wollen, erstellen Sie ein neues array mit den bestehenden ein Teil von Ihr zu sein:
Array spreads sind jetzt unterstützt alle wichtigen Browser aber wenn Sie benötigen, ältere Unterstützung Typoskript oder babel und kompilieren zu ES5.
Mehr info auf spreads
InformationsquelleAutor Luke Femur
Kein jQuery benötigt... Beispiel
Diesen Exemplaren das array aus der Ausgangsposition
0
durch das Ende des Arrays.Es ist wichtig zu beachten, dass es funktionieren wird, wie erwartet, für primitive Typen (string, Zahl, etc.), und auch erklären, das erwartete Verhalten für Referenz-Typen...
Wenn Sie ein array von Referenz-Typen sagen, der Typ
Object
. Das array wird kopiert werden, aber die beiden arrays enthalten Referenzen auf das gleicheObject
's. Also in diesem Fall würde es scheinen, wie das array kopiert wird, die durch Verweis, obwohl das array ist tatsächlich kopiert.Versuchen Sie dieses;
var arr2 = JSON.stringify(arr1); arr2 = JSON.parse(arr2);
Was ist der Unterschied zwischen dieser Antwort und der Antwort akzeptiert?
InformationsquelleAutor jondavidjohn
Alternative zu
slice
istconcat
, die verwendet werden können in 2 Arten. Der erste von diesen ist vielleicht besser lesbar als das beabsichtigte Verhalten ist ganz klar:Die zweite Methode ist:
Cohen (in den Kommentaren) darauf hingewiesen, dass diese letztere Methode hat eine bessere Leistung.
Das funktioniert in der Weise, dass die
concat
- Methode erstellt ein neues array aus den Elementen in das Objekt, auf dem es aufgerufen wird, gefolgt von der Elemente eines arrays übergeben es als argument. So, wenn keine Argumente übergeben werden, wird einfach kopiert, das array.Lee Penkman, auch in den Kommentaren darauf hin, dass, wenn es eine chance
array1
istundefined
können Sie wieder ein leeres array wie folgt:Oder, für die zweite Methode:
Beachten Sie, dass Sie können dies auch tun, mit
slice
:var array2 = (array1 || []).slice();
.Seine erwähnenswert, dass, wenn Matrix1 ist kein array, dann
[].concat(array1)
zurück[array1]
z.B. wenn seine undefined erhalten Sie[undefined]
. Manchmal mache ichvar array2 = [].concat(array1 || []);
InformationsquelleAutor Ninjakannon
Dies ist, wie ich es getan habe nach dem Versuch viele Ansätze:
Dadurch wird eine neue Tiefe Kopie nicht mit der ersten verwandt ist (nicht eine flache Kopie).
Auch diese wird natürlich nicht Klonen, Ereignisse und Funktionen, aber die gute Sache, die Sie tun können, es in eine Zeile, und es kann verwendet werden für jede Art von Objekt (arrays, strings, zahlen, Objekte ...)
Beachten Sie, dass diese option nicht gut umgehen graph-ähnlichen Strukturen: Abstürze in Anwesenheit von Zyklen, und nicht beibehalten freigegebenen Referenzen haben.
Auch dies nicht für Dinge wie
Date
oder in der Tat, alles, was ein Prototyp. Darüber hinausundefined
s umgewandelt zunull
s.Ist niemand mutig genug, um Kommentar auf die grobe Ineffizienz in beiden CPU-und Speicher serialisieren, um text und dann analysieren zurück in ein Objekt?
Diese Lösung ist die einzige, die arbeitete. Mithilfe der slice () - ist wirklich ein fake-Lösung.
InformationsquelleAutor Chtiwi Malek
Einige der genannten Methoden funktionieren auch bei der Arbeit mit einfachen Datentypen wie number oder string, aber wenn das array andere Objekte enthält diese Methoden Versagen. Wenn wir versuchen, Sie zu passieren, wird das Objekt von einem array zu einem anderen übergeben wird, als eine Referenz, nicht das Objekt.
Fügen Sie den folgenden code in der JavaScript-Datei:
Und verwenden Sie einfach
Wird es funktionieren.
Über Welchen Browser hast du diesen Fehler??
Ich bitte um Entschuldigung, dieser Fehler tritt bei chrome, wenn arr1 ist nicht deklariert. also ich Kopie-die oben eingefügten code, und ich bekomme die Fehlermeldung, wenn ich allerdings deklarieren Sie die array arr1, dann Mach ich nicht den Fehler. Sie verbessern könnten, die Antwort, indem er erklärt arr1 nur über arr2, ich sehe, es gibt durchaus ein paar von " uns "gibt, die nicht erkennen, dass wir hatte zu erklären, arr1 (teilweise, weil wenn ich bewerten deine Antwort, ich war in Eile und brauchte etwas, das "einfach funktioniert")
.slice()
funktioniert immer noch gut, auch, wenn Sie Objekte im array: jsfiddle.net/edelman/k525gdie Objekte werden aber immer noch auf das gleiche Objekt so ändern, ändern sich die anderen. jsfiddle.net/k525g/1
InformationsquelleAutor sarvesh singh
Vom ES2015,
InformationsquelleAutor Boopathi Rajaa
Ich persönlich denke, Array.aus ist eine besser lesbare Lösung. Übrigens, nur Hüte dich vor seiner browser-Unterstützung.
.slice()
Lösung ist völlig unintuitiv. Vielen Dank für diese.InformationsquelleAutor Lewis
Wichtig!
Meisten Antworten hier funktioniert für bestimmten Fällen.
Wenn Sie nicht zu tief/verschachtelte Objekte und Requisiten verwenden (ES6):
let clonedArray = [...array]
aber wenn Sie wollen, zu tun, tief-Klon verwenden Sie dieses anstatt:
let cloneArray = JSON.parse(JSON.stringify(array))
Für lodash Benutzer:
let clonedArray = _.clone(array)
Dokumentationund
let clonedArray = _.cloneDeep(array)
DokumentationInformationsquelleAutor ulou
Hinzufügen, um die Lösung array.slice(); bewusst sein, dass, wenn Sie mehrdimensionales array sub-arrays kopiert werden, indem Referenzen.
Was Sie tun können, ist zu loop und slice () - jedes sub-array individuell
gleichen Dinge geht, um ein array von Objekten, Sie werden kopiert, die durch Verweis, die Sie haben, um Sie kopieren manuell
InformationsquelleAutor A.Zaben
Wie wir wissen in Javascript arrays und Objekte sind durch Referenz, sondern, wie wir tun können, kopieren Sie die array-ohne Veränderung des original-array später ein?
Hier sind einige Möglichkeiten, es zu tun:
Vorstellen, dass wir dieses array in deinem code:
1) Schleife durch das array in einer Funktion und zur Rückgabe eines neuen Arrays, wie dieser:
2) Verwendung der slice-Methode die slice steht für schneiden Teil des Arrays, es schneidet einen Teil der Elemente in einem array, ohne den ursprünglichen, in der Scheibe, wenn nicht, geben Sie die start und Ende des Arrays, wird es die Scheibe, die das gesamte array und im Grunde machen eine vollständige Kopie des Arrays, so können wir leicht sagen:
3) Auch die Kontakt-Methode, dies ist für die Zusammenführung der zwei array, aber wir können nur angeben eines arrays und dann diese im Grunde eine Kopie der Werte in den neuen kontaktiert array:
4) Auch stringify und parse-Methode, ist es nicht empfehlenswert, sondern kann eine einfache Möglichkeit zum kopieren von Arrays und Objekten:
5) - Array.von der Methode, diese ist nicht so stark unterstützt wird, bevor Sie verwenden, überprüfen Sie die Unterstützung in den verschiedenen Browsern:
6) ECMA6 Weg, auch nicht vollständig unterstützt, aber babelJs kann Ihnen helfen, wenn Sie wollen transpile:
InformationsquelleAutor Alireza
In meinem speziellen Fall, den ich brauchte, um sicherzustellen, das array intakt geblieben, so dass dies für mich gearbeitet:
InformationsquelleAutor Brent Keller
Machen kopieren von mehrdimensionalen array/Objekt:
Dank James Padolsey für diese Funktion.
Quelle: Hier
InformationsquelleAutor ink
Wenn Sie wollen, um eine neue Kopie von einem Objekt oder array ist, müssen Sie explizit kopieren Sie die Eigenschaften des Objekts oder die Elemente des Arrays, zum Beispiel:
Können Sie Suche nach mehr Informationen bei Google über die unveränderlichen Grundwerte und veränderlichen Objekt-Referenzen.
InformationsquelleAutor Sotiris
Mithilfe von jQuery Tiefe Kopie gemacht werden konnten, wie folgt:
InformationsquelleAutor Alex Tsurika
Können Sie auch verwenden, ES6 spread-operator zum kopieren von Array
InformationsquelleAutor ankur kushwaha
Wenn Ihr array enthält Elemente der primitiven Datentyp wie int, char oder string, etc. dann können Sie Benutzer einer dieser Methoden liefert eine Kopie des ursprünglichen Arrays wie .slice () - oder .map() oder spread-operator(Dank ES6).
oder
oder
ABER wenn Ihr array enthält komplexe Elemente wie Objekte(und arrays) oder mehr verschachtelte Objekte, dann werden Sie haben, um sicherzustellen, dass Sie eine Kopie aller Elemente aus der obersten Ebene, um die Letzte Stufe sonst Referenz auf die inneren Objekte verwendet werden, und das bedeutet, dass der Wertewandel in object_elements in new_array wird noch Einfluss auf die old_array. Sie können diese Methode aufrufen, kopieren, auf jeder Ebene, wie eine TIEFE KOPIE
der old_array.
Für tiefes kopieren, können Sie die oben genannten Methoden für die primitiven Datentypen auf jeder Ebene je nach Art der Daten, oder Sie können verwenden Sie diese kostspielige Methode(weiter unten erwähnt) für eine Tiefe Kopie ohne viel zu tun.
Gibt es viele andere Methoden gibt, die Sie verwenden können, je nach Ihren Anforderungen. Habe ich erwähnt, nur einige von denen, dass Sie eine Allgemeine Vorstellung von dem, was passiert, wenn wir versuchen, Sie zu kopieren, eine array in das andere von Wert.
InformationsquelleAutor Abhinav1602
Hier ist eine Variante:
toSource
ist nicht standard und funktioniert nicht in Chrome zum Beispiel.InformationsquelleAutor Zyox
Gibt es die neu eingeführten
Array.from
, aber leider, wie der Zeitpunkt des Schreibens dieses Artikels, es ist nur gestützt auf neuere Firefox-Versionen (32 und höher). Es kann einfach benutzt werden, wie folgt:Referenz: Hier
Oder
Array.prototype.map
kann verwendet werden, mit einem identity-Funktion:Referenz: Hier
Array.from
, die jetzt unterstützt auf allen gängigen Browsern außer dem Internet Explorer (Quelle). .InformationsquelleAutor Ashraf Sabry
Können Sie dies in folgender Weise :
arr2 = arr1.map(x => Object.assign({}, x));
InformationsquelleAutor Harunur Rashid
Könnten Sie ES6 mit ausgebreiteten Opeartor, einfacher.
Gibt es Einschränkungen..check docs Verbreiten syntax @ mozilla
InformationsquelleAutor BluePie
Hier ist, wie Sie es tun können für die array von arrays von primitive-variable Tiefe:
https://jsbin.com/xemazog/edit?js,Konsole
InformationsquelleAutor G.Denis
Primitive Werte werden immer übergeben, indem Sie den Wert (übernommen). Zusammengesetzte Werte hovever Verweis übergeben werden.
So, wie kopieren wir diese arr?
Kopieren eines Arrays in ES6
Copy n Array in ES5
Warum `lassen arrCopy = arr` ist kein Wert übergeben?
Übergeben einer Variable an eine andere Verbindung auf Werte wie Objekt/Array Verhalten difrently. Mit Zeichen-operator auf copand Werte, die wir übergeben die Referenz auf ein Objekt. Dies ist der Grund, warum der Wert der beiden arrays ändern, wenn entfernen/hinzufügen arr Elemente.
Exceptios:
Wenn Sie einen neuen Wert zuweisen, um die variable, ändern Sie die Referenz selbst, und es wirkt sich nicht auf das ursprüngliche Objekt/Array.
Lesen Sie mehr
InformationsquelleAutor DevWL
Nun können Sie eine der folgenden Optionen, um eine Kopie eines Arrays.
ODER
ODER
ODER
ODER
Nun, wenn ich eine änderung ein,
Dann ist a [1,2,3,5], aber b ist noch [1,2,3], wie es hat verschiedene Referenz.
Aber ich denke, in all den obigen Methoden Array.aus besser ist und hauptsächlich zum kopieren eines Arrays.
InformationsquelleAutor Nitesh Ranjan