Variabler Typ und SpeicherplatzStapelspeicher und Heap-SpeicherGrundlegende DatentypenZeichenfolge, Zahl, Null, undefiniert, Boolesch, Symbol (neu in ES6) Variablenwerte werden im Stapelspeicher gespeichert, und die Werte von Variablen können direkt abgerufen und geändert werden. Grundlegende Datentypen haben keine Kopien, beispielsweise können Sie den Wert von 1 nicht ändern. Referenztypen Objekt Funktion RegExp Math Date Der Wert ist ein Objekt, welches im Heap-Speicher abgelegt wird. Die Variable im Stack-Speicher speichert einen Zeiger auf die entsprechende Adresse im Heap-Speicher. Grafischer Speicherplatzlet a1 = 0; // Stapelspeicher let a2 = "this is string" // Stapelspeicher let a3 = null; // Stapelspeicher let b = { x: 10 }; // Variable b existiert im Stapel, { x: 10 } existiert als Objekt im Heap let c = [1, 2, 3]; // Variable c existiert im Stapel, [1, 2, 3] existiert als Objekt im Heap Zuordnung von Verweistypensei a = { x: 10, y: 20 } sei b = a; bx = 5; konsole.log(ax); // 5 Tiefe Kopie und flache KopieTiefes KopierenKopieren Sie ein Objekt vollständig aus dem Speicher, öffnen Sie einen neuen Bereich im Heap-Speicher, um das neue Objekt zu speichern, und ändern Sie das neue Objekt. Dies hat keine Auswirkungen auf das ursprüngliche Objekt. Flache KopieEine oberflächliche Kopie ist eine bitweise Kopie eines Objekts, die ein neues Objekt mit einer exakten Kopie der Eigenschaftswerte des Originalobjekts erstellt. Wenn das Attribut ein primitiver Typ ist, wird der Wert des primitiven Typs kopiert; wenn das Attribut eine Speicheradresse (Referenztyp) ist, wird die Speicheradresse kopiert. Zuordnung von ObjektenWenn wir einer neuen Variablen ein Objekt zuweisen, wird tatsächlich die Adresse des Objekts im Stapel zugewiesen, nicht die Daten im Heap. Das heißt, die beiden Objekte verweisen auf denselben Speicherplatz. Unabhängig davon, welches Objekt sich ändert, ändert sich tatsächlich der Inhalt des Speicherplatzes. Daher sind die beiden Objekte verknüpft. Vergleich der dreiFünf gängige Methoden des Shallow CopyObjekt.zuweisen()Die Methode Object.assign() kann eine beliebige Anzahl aufzählbarer Eigenschaften des Quellobjekts in das Zielobjekt kopieren und dann das Zielobjekt zurückgeben. Aber Object.assign() führt eine oberflächliche Kopie durch Object.assign durchläuft alle Eigenschaften des Quellobjekts (Quellen) von links nach rechts und weist sie dann mit = dem Zielobjekt (Ziel) zu. var obj = { a: {a: "kobe", b: 39},b:1 }; var initialObj = Object.assign({}, obj); initialObj.aa = "waten"; initialObj.b = 2; console.log(obj.aa); //waten console.log(obj.b); //1 Spread-Operatorsei obj = {a:1,b:{c:1}} sei obj2 = {...obj}; Objekt.a=2; console.log(obj); //{a:2,b:{c:1}} console.log(obj2); //{a:1,b:{c:1}} obj.bc = 2; console.log(obj); //{a:2,b:{c:2}} console.log(obj2); //{a:1,b:{c:2}} Array.Prototyp.ScheibeDie Methode slice() gibt ein neues Array-Objekt zurück, das eine oberflächliche Kopie des durch begin und end (ohne end) bestimmten Original-Arrays ist. Der Basistyp des ursprünglichen Arrays wird nicht geändert, aber der Referenztyp wird geändert. sei arr = [1, 3, { Benutzername: „kobe“ }]; lass arr3 = arr.slice(); arr3[0]=0; arr3[2].Benutzername = "wade" Konsole.log(arr); Array.prototype.concat()sei arr = [1, 3, { Benutzername: „kobe“ }]; lass arr2=arr.concat(); arr3[0]=0; arr2[2].Benutzername = "wade"; Konsole.log(arr); Handschriftliche oberflächliche KopieFunktion flacheKopie(Quelle) { var dst = {}; für (var prop in src) { wenn (src.hasOwnProperty(prop)) { dst[Eigenschaft] = src[Eigenschaft]; } } Rückgabeziel; } Gängige Methoden für Deep CopyjsON.parse(jsON.stringify())Bei der Implementierung von Deep Copy über JSON.stringify sind einige Dinge zu beachten Wenn der Wert des kopierten Objekts eine Funktion, ein undefiniertes Element oder ein Symbol enthält, verschwindet das Schlüssel-Wert-Paar in der von JSON.stringify() serialisierten JSON-Zeichenfolge. Nicht aufzählbare Eigenschaften können nicht kopiert werden. Die Prototypenkette des Objekts kann nicht kopiert werden. Durch Kopieren des Datumsreferenztyps wird eine Zeichenfolge erstellt Das Kopieren eines RegExp-Referenztyps führt zu einem leeren Objekt Wenn das Objekt NaN, Infinity und -Infinity enthält, wird das serialisierte Ergebnis null Objekte können nicht in einer Schleife kopiert werden (z. B. obj[key] = obj) sei arr = [1, 3, { Benutzername: „kobe“ }]; Lassen Sie arr4 = JSON.parse(JSON.stringify(arr)); arr4[2].Benutzername = "duncan"; konsole.log(arr, arr4) Handgeschriebene Beggar's Edition Deep CopyZunächst einmal kann diese DeepClone-Funktion keine nicht aufzählbaren Eigenschaften und Symboltypen kopieren. Hier wird die Schleifeniteration nur für den Wert des Objektreferenztyps durchgeführt und die Array-, Datums-, RegExp-, Fehler- und Funktionsreferenztypen können nicht korrekt kopiert werden. Objekte werden geloopt, d.h. zirkuläre Referenzen (z.B. obj1.a = obj) Funktion Klon(Ziel) { wenn (Typ des Ziels === 'Objekt') { Lassen Sie cloneTarget = Array.isArray(target) ? [] : {}; für (const key in target) { cloneTarget[Schlüssel] = Klon(Ziel[Schlüssel]); } gibt Klonziel zurück; } anders { Rücklaufziel; } }; Kaiser Edition - Vollständige KopieDieses Beispiel stammt von ConardLis GitHub, Quelladresse: https://github.com/ConardLi/ const mapTag = "[Objektzuordnung]"; const setTag = "[Objektsatz]"; const arrayTag = "[Objekt-Array]"; const objectTag = "[Objekt Objekt]"; const argsTag = "[Objektargumente]"; const boolTag = "[Objekt Boolean]"; const dateTag = "[Objekt Datum]"; const numberTag = "[Objektnummer]"; const stringTag = "[Objekt String]"; const symbolTag = "[Objekt Symbol]"; const errorTag = "[Objektfehler]"; const regexpTag = "[Objekt RegExp]"; const funcTag = "[Objektfunktion]"; const deepTag = [mapTag, setTag, arrayTag, objectTag, argsTag]; Funktion fürJeden(Array, Iteratee) { lass Index = -1; const Länge = Array.Länge; während (++Index < Länge) { iterieren(Array[Index], Index); } Array zurückgeben; } Funktion istObjekt(Ziel) { const Typ = Typ des Ziels; Rückgabeziel !== null && (Typ === "Objekt" || Typ === "Funktion"); } Funktion getType(Ziel) { gibt Object.prototype.toString.call(Ziel) zurück; } Funktion getInit(Ziel) { const Ctor = Ziel.Konstruktor; gib neuen Ctor() zurück; } Funktion KlonSymbol(Ziel) { gibt Objekt zurück (Symbol.prototype.valueOf.call(target)); } Funktion cloneReg(Ziel) { const reFlags = /\w*$/; const Ergebnis = neuer Zielkonstruktor (Ziel.Quelle, reFlags.exec (Ziel)); Ergebnis.letzterIndex = Ziel.letzterIndex; Ergebnis zurückgeben; } Funktion Klonfunktion(func) { const bodyReg = /(?<={)(.|\n)+(?=})/m; const paramReg = /(?<=\().+(?=\)\s+{)/; const funcString = func.toString(); wenn (Funktion.Prototyp) { const param = paramReg.exec(funcString); const body = bodyReg.exec(funcString); wenn (Körper) { wenn (Param) { const paramArr = param[0].split(","); gib eine neue Funktion zurück (...paramArr, body[0]); } anders { gib eine neue Funktion zurück (Body[0]); } } anders { gibt null zurück; } } anders { gibt eval(Funktionsstring) zurück; } } Funktion cloneOtherType(Ziel, Typ) { const Ctor = Ziel.Konstruktor; Schalter (Typ) { Fall boolTag: FallnummerTag: Fall-StringTag: FallfehlerTag: FalldatumTag: gib neuen Ctor(Ziel) zurück; Fall RegexpTag: returniere cloneReg(Ziel); FallsymbolTag: gibt KlonSymbol(Ziel) zurück; Fall-FunktionsTag: gibt Klonfunktion (Ziel) zurück; Standard: gibt null zurück; } } Funktion Klon(Ziel, Karte = neue WeakMap()) { // Den Originaltyp klonen if (!isObject(target)) { Rücklaufziel; } // Initialisieren const type = getType(target); lass Ziel klonen; wenn (deepTag.includes(Typ)) { cloneTarget = getInit(Ziel, Typ); } anders { returniere cloneOtherType(Ziel, Typ); } // Zirkelreferenzen vermeiden if (map.get(target)) { Karte zurückgeben.get(Ziel); } map.set(Ziel, Klonziel); // Klonen Sie das Set wenn (Typ === setzeTag) { ziel.fürJeden(Wert => { cloneTarget.add(Klon(Wert, Karte)); }); gibt Klonziel zurück; } // Die Karte klonen wenn (Typ === MapTag) { target.forEach((Wert, Schlüssel) => { cloneTarget.set(Schlüssel, Klon(Wert, Map)); }); gibt Klonziel zurück; } // Objekte und Arrays klonen const keys = Typ === ArrayTag ? undefiniert : Object.keys(Ziel); fürJeden(Schlüssel || Ziel, (Wert, Schlüssel) => { wenn (Schlüssel) { Schlüssel = Wert; } cloneTarget[Schlüssel] = Klon(Ziel[Schlüssel], Map); }); gibt Klonziel zurück; } const map = neue Map(); map.set("Schlüssel", "Wert"); map.set("ConardLi", "Code Geheimer Garten"); const set = neues Set(); setze.add("ConardLi"); set.add("Code geheimer Garten"); const Ziel = { Feld1: 1, Feld2: undefiniert, Feld3: { Kind: "Kind" }, Feld4: [2, 4, 8], leer: null, Karte, Satz, bool: neuer Boolean(true), num: neue Zahl(2), str: neuer String(2), Symbol: Objekt(Symbol(1)), Datum: neues Datum(), reg: /\d+/, Fehler: neuer Fehler(), func1: () => { console.log("Code geheimer Garten"); }, func2: Funktion(a, b) { gib a + b zurück; } }; const Ergebnis = Klon(Ziel); konsole.log(Ziel); console.log(Ergebnis); Oben finden Sie eine ausführliche Erläuterung zu Deep Copy und Shallow Copy von JS-Variablenspeicher. Weitere Informationen zu Deep Copy und Shallow Copy von JS-Variablenspeicher finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: 18 allgemeine Befehle in der MySQL-Befehlszeile
Vue+Openlayer verwendet „modify“, um Elemente zu ...
MySQL-Fehler: Parameterindex außerhalb des gültig...
Inhaltsverzeichnis Einführung in den Vue-Lebenszy...
XML/HTML-CodeInhalt in die Zwischenablage kopiere...
1. Lösung 1.1 Beschreibung des Schnittstellenkont...
Erstellen Sie in MySQL eine Ansicht für zwei oder...
Das Erlernen von Linux-Befehlen stellt für die me...
Rand paralleler Boxen (Überlappung doppelter Ränd...
Code kopieren Der Code lautet wie folgt: <Obje...
So ermöglichen Sie Tomcat die Unterstützung des h...
Inhaltsverzeichnis 1. existiert 1.1 Beschreibung ...
In diesem Artikel wird der spezifische Code von V...
Beim Einfügen eines Datensatzes in die MySQL-Date...
Beschränken Sie input Eingabefeld auf reine Zahle...
Inhaltsverzeichnis Umgebungsbeschreibung Installi...