VorwortAls ich zuvor „defineProperty“ vorgestellt habe, habe ich erwähnt, dass es nur Änderungen an Objekten überwachen kann, nicht jedoch Änderungen in Arrays. In diesem Artikel wird erläutert, wie Array-Änderungen überwacht werden. Kernidee: Finden Sie Wege, das ursprüngliche Array zu ändern, und kapern Sie dann diese Methoden. Der obige Satz ist von größter Wichtigkeit. Lesen Sie ihn unbedingt dreimal und merken Sie ihn sich, bevor Sie fortfahren. Zu den häufig verwendeten Methoden zum Ändern des ursprünglichen Arrays zählen Push, Pop, Shift und Unshift, Reverse, Sort und Splice. Mit anderen Worten: Diese Methoden ändern die Einträge des Arrays. Fügen Sie zwischen der Array-Instanz und dem Array-Prototyp einen neuen Prototyp hinzuDie direkte Änderung von Array.prototype ist äußerst gefährlich. Ändern Sie Ihre Meinung, kopieren Sie den vorhandenen Array-Prototyp und ändern Sie dann die Methoden darin. Hier können die Methoden des Prototyps jedoch nicht kopiert werden, da sie nicht aufzählbar sind. Ändern wir also unsere Denkweise. Wir können einen Prototyp zwischen dem Array und dem Prototyp des Arrays einfügen, um eine Prototypenkette zu bilden: Array => neuer Prototyp => Prototyp des Arrays. Wir können dann dem neuen Prototyp eine Methode mit demselben Namen hinzufügen. Verwenden Sie zunächst Pseudocode, um Folgendes zu verstehen: // Pseudocode let arr = []; arr.__proto__ = neuer Prototyp; neuerPrototype.__proto__ = Array.prototype; // Dann können Sie dem neuen Prototyp eine Methode mit demselben Namen hinzufügen newPrototype.push = xxx; Der eigentliche Code lautet wie folgt. Der Kern verwendet Object.create. // Object.create gibt ein neues Objekt zurück und das __proto__ des neuen Objekts ist der übergebene Parameter. Fügt neue Prototypen zu Object.create(Array.prototype); // Dann können Sie dem neuen Prototyp eine Methode mit demselben Namen hinzufügen newPrototype.push = xxx; // Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = []; arr.__proto__ = neuer Prototyp; Nehmen Sie Push als Beispiel, kapern Sie PushSchreiben Sie dazu einfach eine Push-Methode auf den neuen Prototypen, die den alten Push ausführt, aber auch noch etwas anderes kann. Fügt neue Prototypen zu Object.create(Array.prototype); // Füge dem neuen Prototyp einen Push mit dem gleichen Namen hinzu neuerPrototype.push = Funktion(...args) { // Semantisches dies lass curArr = dies; console.log("Push wird verwendet"); // Abschließend wird der ursprüngliche Push ausgeführt gibt Array.prototype.push.call(curArr, ...args) zurück; }; // Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = []; arr.__proto__ = neuer Prototyp; // Wenn Push ausgeführt wird, wird arr.push(1) gedruckt; Dann sind andere Methoden ähnlich. Versuchen Sie, andere Methoden zu schreiben Andere Methoden kapernDie anderen Methoden werden auch zusammen geschrieben, da die Logik dieselbe ist und direkt durchlaufen werden kann. Fügt neue Prototypen zu Object.create(Array.prototype); let-Methoden = ["push", "pop", "shift", "unshift", "reverse", "sort", "spleißen"]; Methoden.fürJedes(Methode => { neuerPrototyp[Methode] = Funktion(...Argumente) { console.log(`${method} verwendet`); gibt Array.prototype[Methode].call(diese, ...args) zurück; }; }); // Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = []; arr.__proto__ = neuer Prototyp; // Bei der Ausführung wird arr.push(1) gedruckt; arr.pop(); Wenn das Array Array-Elemente enthält, müssen diese ebenfalls überwacht werdenHier kann sich ein Array im Array befinden, und jedes Element im Array muss durchlaufen werden. Wenn es sich um ein Array handelt, muss es dennoch auf den neuen Prototyp verweisen. Ja, es wird Rekursion verwendet. Fügt neue Prototypen zu Object.create(Array.prototype); let-Methoden = ["push", "pop", "shift", "unshift", "reverse", "sort", "spleißen"]; Methoden.fürJedes(Methode => { neuerPrototyp[Methode] = Funktion(...Argumente) { console.log(`${method} verwendet`); gibt Array.prototype[Methode].call(diese, ...args) zurück; }; }); Funktion beobachteArr(arr) { // Es ist sowohl eine bedingte Einschränkung als auch eine rekursive Abbruchbedingung, wenn (!Array.isArray(arr)) { zurückkehren; } // Das gesamte Array zeigt auf den neuen Prototyp arr.__proto__ = newPrototype; // Jedes Element im Array, sofern es ein Array ist, verweist auch auf den neuen Prototyp. arr.forEach(beobachtenArr); } // Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = [[1, 2, 3]]; beobachteArr(arr); // Bei der Ausführung wird arr[0].push(1) gedruckt; arr[1].pop(); Neue Elemente, die dem Array hinzugefügt werden, müssen, wenn es sich um ein Array handelt, auch auf den neuen Prototyp verweisenMethoden, die Elemente hinzufügen können: Push, Unshift, Splice. Suchen Sie nach dem neu hinzugefügten Element. Anschließend zeigt das Array auch auf den neuen Prototyp Fügt neue Prototypen zu Object.create(Array.prototype); let-Methoden = ["push", "pop", "shift", "unshift", "reverse", "sort", "spleißen"]; Methoden.fürJedes(Methode => { neuerPrototyp[Methode] = Funktion(...Argumente) { console.log(`${method} verwendet`); eingefügt lassen; Schalter (Methode) { Fall "push": Fall "unshift": eingefügt = Argumente; brechen; Fall "Spleißen": eingefügt = args.slice(2); brechen; Standard: brechen; } eingefügt und observeArr (eingefügt); gibt Array.prototype[Methode].call(diese, ...args) zurück; }; }); Funktion beobachteArr(arr) { // Es ist sowohl eine bedingte Einschränkung als auch eine rekursive Abbruchbedingung, wenn (!Array.isArray(arr)) { zurückkehren; } // Das gesamte Array zeigt auf den neuen Prototyp arr.__proto__ = newPrototype; // Jedes Element im Array, sofern es ein Array ist, verweist auch auf den neuen Prototyp. arr.forEach(beobachtenArr); } // Dies kann exportiert werden, um die Verwendung anderer Dateien zu erleichtern. Exportieren Sie standardmäßig „objectArr“. // Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = []; beobachteArr(arr); Lassen Sie addItem = [1, 2, 3]; arr.push(Element hinzufügen); // Bei der Ausführung wird addItem.push(1) gedruckt; addItem.pop(); Kombinierte Verwendung von defineProperty zur Überwachung von Objekten und ArraysJetzt haben wir Methoden zum Überwachen von Objekten und Methoden zum Überwachen von Arrays. Durch die Kombination der beiden können wir Objekte in Arrays und Arrays in Objekten überwachen. Das Überwachungsarray und das Überwachungsobjekt können zur späteren Verwendung in eine separate Datei geschrieben werden. Um die direkte Codeausführung zu ermöglichen, werden sie hier zusammengefasst. /** * observeArr-Teil**/ // Einen neuen Prototyp generieren let newPrototype = Object.create(Array.prototype); let-Methoden = ["push", "pop", "shift", "unshift", "reverse", "sort", "spleißen"]; // Füge die obige Methode zum neuen Prototyp hinzu, um methods.forEach(method => { zu kapern. neuerPrototyp[Methode] = Funktion(...Argumente) { console.log(`${method} verwendet`); eingefügt lassen; Schalter (Methode) { Fall "push": Fall "unshift": eingefügt = Argumente; brechen; Fall "Spleißen": eingefügt = args.slice(2); brechen; Standard: brechen; } eingefügt und observeArr (eingefügt); gibt Array.prototype[Methode].call(diese, ...args) zurück; }; }); Funktion beobachteArr(arr) { // Neu! ! ! Wenn es ein Objekt ist, müssen Sie das Objekt verwenden, wenn (Object.prototype.toString.call(arr) === "[object Object]") { beobachteObj(arr); zurückkehren; } wenn (Array.isArray(arr)) { // Das gesamte Array zeigt auf den neuen Prototyp arr.__proto__ = newPrototype; // Jedes Element im Array, sofern es ein Array ist, verweist auch auf den neuen Prototyp. arr.forEach(beobachtenArr); } // Kein Objekt oder Array, nichts tun} /** * observeObj-Teil**/ Funktion Obj beobachten(Objekt) { // Parameterbeschränkungen hinzufügen, es können nur Objekte gekapert werden, was auch die Abbruchbedingung der Rekursion ist, wenn (typeof obj !== "object" || obj == null) { zurückkehren; } // Neu! ! ! Array wird zur Verarbeitung an Array übergeben, wenn (Array.isArray(obj)) { beobachteArr(Objekt); zurückkehren; } // Rekursion nur starten, wenn es sich um ein Objekt handelt for (let key in obj) { // Die direkte Verwendung von obj.hasOwnProperty führt zu einem nicht standardmäßigen if (Object.prototype.hasOwnProperty.call(obj, key)) { observeKey(Objekt, Schlüssel); // Hier wird der Attributwert des Attributs gekapert. Wenn es kein Objekt ist, wird es direkt zurückgegeben, ohne Auswirkungen auf observeObj(obj[key]); } } gibt Objekt zurück; } Funktion observeKey(Objekt, Schlüssel) { let value = obj[Schlüssel]; Objekt.defineProperty(Objekt, Schlüssel, { erhalten() { console.log("Eigenschaften lesen", Wert); Rückgabewert; }, setze(neuerWert) { console.log("Eigenschaften festlegen", neuerWert); Wert = neuerWert; } }); } /** * Probieren Sie die Demo aus**/ lass Daten = { a: 1, b: [1, 2, { c: 2 }] }; Obj beobachten(Daten); Daten.a = 2; daten.b.push([2, 3]); let arr = [{ a: "Objekt im Array" }, 3, 4]; beobachteArr(arr); arr[0].a = 3; DefektNatürlich können Arrays auch ohne Methoden verändert werden. So kann man beispielsweise ein Array löschen, indem man das Längenattribut verwendet, oder man kann das Array direkt verändern, indem man arr[0]=xxx verwendet. Array-Änderungen können jedoch nur bei Verwendung von „Push“, „Pop“, „Shift“, „Unshift“, „Reverse“, „Sort“ und „Splice“ erkannt werden. Dies ist auch ein Defekt von Vue. Natürlich wird die neue Version des Proxys diesen Defekt beheben. Versuchen Sie daher bei Verwendung von Vue, das Array mit der oben beschriebenen Methode zu betreiben~~~ Hinweis: Alle Eigenschaften und Methoden von Arrays anzeigenSie können dir([]) in die Konsole eingeben und dann alle Eigenschaften und Methoden des Arrays sehen. Für spezifische Verwendungszwecke können Sie direkt zu mdn gehen und auf die Seitenleiste klicken, um die entsprechende Methode anzuzeigen ZusammenfassenDies ist das Ende dieses Artikels zum Überwachen von Array-Änderungen mit JavaScript. Weitere relevante Inhalte zum Überwachen von Array-Änderungen mit JS finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den verwandten Artikeln weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Implementierungsschritte zum Erstellen eines lokalen Webservers auf Centos8
>>: So ändern Sie das Root-Benutzerkennwort in MySQL 8.0.16, WinX64 und Linux
Der IE hat schon seit längerem Probleme. Als alle ...
Inhaltsverzeichnis Frage: Es gibt 2 Token im Proj...
Das Projekt wurde in diesen Tagen getestet und de...
Code kopieren Der Code lautet wie folgt: <span...
Der Grund für das Schreiben dieses Artikels beste...
1. Ereignissprudeln : Wenn im Prozess der Ereigni...
1. Allgemeine Verwendung: (1) Mit % verwenden % s...
1. Wie konstruieren? Lassen Sie uns die allgemein...
Heute teile ich die wertvollen Erfahrungen eines ...
Dieses Tutorial beschreibt Ihnen die detaillierte...
CSS-Attributselektoren sind großartig. Sie können...
=================================================...
Viele Freunde berichten von folgendem Fehler, wen...
Klicken Sie hier, um zum Abschnitt „HTML-Tutorial“...
Finden Sie das Problem Beim Abrufen der wichtigst...