VorwortdefineProperty ist der Kern von Vue, um Datenentführung zu erreichen. Dieser Artikel erklärt Schritt für Schritt, wie defineProperty die Datenentführung erreicht. Tatsächlich bedienen wir Objekteigenschaften im Allgemeinen auf die Art und Weise, wie wir Eigenschaften hinzufügen oder ändern, und wir können Object.defineProperty verwenden. lass obj = {}; // Allgemeiner Vorgang: Neues Attribut hinzufügen/ändern obj.a = 1; // ist gleichbedeutend mit: Objekt.defineProperty(o, "a", { Wert: 1, beschreibbar: true, konfigurierbar: true, aufzählbar: wahr }); Natürlich würden wir es in normalen Beispielen nicht auf diese Weise spielen, da es zu langatmig wäre. Mit „defineProperty“ können die Eigenschaften eines Objekts jedoch präziser hinzugefügt oder geändert werden. DeskriptorenLassen Sie mich mit einem Eigennamen beginnen: Deskriptor. Tatsächlich ist es der dritte Parameter von defineProperty, bei dem es sich um ein Objekt handelt. Dieses Objekt hat die folgenden Eigenschaften:
Beachten! ! !
Detaillierte Erklärung von get und set
Wiederholen Sie dies dreimal still und merken Sie es sich. Schreiben Sie zum besseren Verständnis ein Beispiel für „get“ und „set“. Dieses Beispiel muss gemeistert werden. Wenn Sie es verstanden haben, werden Sie im Wesentlichen das Wesen des Datendiebstahls verstehen. lass obj = {}; lass Wert = 1; Objekt.defineProperty(obj, "b", { erhalten() { console.log("Attribut b lesen", Wert); Rückgabewert; }, setze(neuerWert) { console.log("Eigenschaft b festlegen", neuerWert); Wert = neuerWert; } }); // Löse die get-Funktion aus, der Rückgabewert von get ist der Attributwert // 1 Konsole.log(Objekt.b); //Set-Funktion auslösen, der Wert wird 2, beachten! ! ! Zu diesem Zeitpunkt hat sich der Attributwert im Speicher nicht geändert obj.b = 2; // Wenn Sie jedoch den Eigenschaftswert lesen möchten, wird die Get-Funktion zwangsläufig ausgelöst und der Eigenschaftswert ändert sich natürlich. Diese Idee ist wirklich gut console.log(obj.b); Hier gibt es eine Falle: In get dürfen keine Leseoperationen vorkommen, sonst entsteht eine Endlosschleife. Wo also get set verwendet wird, wird immer eine Variable benötigt. Der Wert der Variablen value ist hier also der Wert des Attributs. Wenn Sie das Attribut ändern möchten, ändern Sie einfach den Wert von value. Ich denke, das reicht aus, um nach dem Verständnis dieses Beispiels die Essenz von Get und Set zu verstehen. Entführung eines Attributs eines ObjektsVersuchen Sie, basierend auf dem vorherigen Beispiel, eine beliebige Eigenschaft des entführten Objekts zu schreiben. 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; } }); } lass obj = { a: 1 }; beobachteSchlüssel(Objekt, "a"); // Lesen Sie a, lösen Sie die Get-Funktion aus console.log(obj.a); // Setze a, löse die Setzfunktion aus obj.a = 1; Alle Eigenschaften eines Objekts kapernVersuchen Sie, alle Eigenschaften des Objekts zu übernehmen Tatsächlich handelt es sich um eine Durchquerung: Funktion Obj beobachten(Objekt) { für (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); } } 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; } }); } sei Objekt = { a: 1, b: 2 }; beobachteObjekt(Objekt); konsole.log(obj); // Lesen Sie a, lösen Sie die Get-Funktion aus console.log(obj.a); // Setze a, löse die Setzfunktion aus obj.a = 1; Alle Eigenschaften eines Objekts kapern - einschließlich des Eigenschaftswerts des ObjekttypsDas Obige weist einen Fehler auf: Wenn der Attributwert auch ein Objekt ist, kann der Attributwert nicht entführt werden, z. B. {a:1,c:{b:1}} Einfach, Rekursion, füllen Sie es einfach aus. 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; } für (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; } }); } lass obj = { a: 1, b: 2, c: { name: "c" } }; beobachteObjekt(Objekt); konsole.log(obj); // Lesen Sie a, lösen Sie die Get-Funktion aus console.log(obj.a); // Setze a, löse die Setzfunktion aus obj.a = 1; // Trigger-Set-Funktion obj.c.name = "d"; Beachten Sie, dass die Funktion „objectObj“ keine neuen Eigenschaften eines Objekts übernehmen kann, sondern nur die vorhandenen Eigenschaften des Objekts. Die Nachteile von defineProperty
Natürlich können Array-Änderungen auch auf andere Weise überwacht werden, was durch die Entführung der Array-Änderungsmethode erreicht wird. Die oben genannten Mängel sind auch der Grund, warum es in Vue $set/$delete gibt und warum Arrays nur mit bestimmten Methoden erkannt werden können. sei Objekt = { a: 1, b: [1, 2] }; beobachteObjekt(Objekt); // Neue Attribute hinzufügen obj.c = 3; // Löst die Get-Funktion nicht aus console.log(obj.c); // Löst die Set-Funktion nicht aus obj.b.push(3); defineProperty kann auch Eigenschaften mountenTatsächlich handelt es sich um den Zugriff auf options.data.name, was als options.name abgekürzt werden kann, ein Fachbegriff, um die Attribute auf Daten an Optionen anzuhängen Dies entspricht der Verwendung von defineProperty zum Hinzufügen neuer Eigenschaften zu Optionen: // Mounten Sie zuerst ein einzelnes Attribut // options.data entspricht Quelle, options entspricht Ziel Funktion ProxyKey(Ziel, Quelle, Schlüssel) { Object.defineProperty(Ziel, Schlüssel, { // Hier ist source[key] gleichbedeutend mit dem Variablenwert, daher ist das einfachste Beispiel das Kern-get() { Rückgabequelle [Schlüssel]; }, setze(neuerWert) { wenn (neuerWert === Quelle[Schlüssel]) { zurückkehren; } Quelle[Schlüssel] = neuerWert; } }); } // Durchlaufe die Attribute und mounte die Funktion proxyObj(target, source) { für (let-Schlüssel in Quelle) { // Die direkte Verwendung von obj.hasOwnProperty führt zu einem nicht standardmäßigen if (Object.prototype.hasOwnProperty.call(source, key)) { ProxyKey(Ziel, Quelle, Schlüssel); } } } let Optionen = { Daten: { Name: 1 } }; ProxyObj(Optionen, Optionen.Daten); // 1 konsole.log(Optionen.Name); Übrigens sind die Grundprinzipien der Attribut-Entführung und des Mountens von Attributen in Vue fast dieselben wie oben. defineProperty kann auch Protokolle schreibenBeispielsweise hat obj ein Attribut, dessen Wert sich häufig ändert, und wir möchten alle seine geänderten Werte aufzeichnen, um ein Protokoll zu erstellen. lass obj = { a: 1 }; lass log = [Objekt.a]; sei Wert = Objekt.a; Objekt.defineProperty(obj, "a", { erhalten() { Rückgabewert; }, setze(neuerWert) { wenn (neuerWert === Wert) { zurückkehren; } Wert = neuerWert; log.push(neuerWert); } }); obj.a = 2; obj.a = 3; obj.a = 4; // [1,2,3,4] konsole.log(log); Um die Änderungen eines bestimmten Wertes aufzuzeichnen, kann eine allgemeine Klasse extrahiert werden. Klasse Archiver { Konstruktor() { lass Wert = null; dieses.archive = []; Objekt.defineProperty(dies, "a", { erhalten() { Rückgabewert; }, setze(neuerWert) { wenn (neuerWert === Wert) { zurückkehren; } Wert = neuerWert; dies.archive.push(neuerWert); } }); } } let Archiver = neuer Archiver(); Archivierer.a = 1; Archivierer.a = 2; // [1,2] Konsole.log(Archivierer.Archiv); Verweise defineProperty von MDN ZusammenfassenDies ist das Ende dieses Artikels über die Implementierung von Property Hijacking mit JavaScript defineProperty. Weitere verwandte Inhalte zum Property Hijacking von defineProperty finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! |
<<: Ubuntu Docker-Installation in VMware (Containererstellung)
>>: Mysql löst das N+1-Abfrageproblem der Datenbank
Ursachen und Folgen 1. Wenn Sie den Ansible-Befeh...
MySQL-Anweisungen zum Hinzufügen, Löschen, Ändern...
Wenn wir möchten, dass mehr Leute die von uns ers...
Beim Erstellen von Datenbankstatistiken müssen Si...
Vorwort Bei der Verwendung einer MySQL-Datenbank ...
Es gibt viele Versionen der Java-Sprache. Zusätzl...
führen Einige gängige Dreiecke auf Webseiten könn...
Der folgende Inhalt stellt den Prozess und die Lö...
GTID-basierte Replikation Einführung Die GTID-bas...
Kürzlich wurde die neue Anforderung „Front-End-Ca...
Beim Verwenden des XAML-Layouts müssen manchmal ei...
Vorwort Ich habe mir die zuvor veröffentlichten A...
Lösung für das Problem der automatischen Trennung...
HTML-Teil Code kopieren Der Code lautet wie folgt:...
Hintergrund: Hoch- und Herunterladen von Dateien ...