Eine kurze Erläuterung des Lazy-Loading-Attributmusters in JavaScript

Eine kurze Erläuterung des Lazy-Loading-Attributmusters in JavaScript

1. Einleitung

Traditionell erstellen Entwickler Eigenschaften in JavaScript-Klassen für alle Daten, die in einer Instanz benötigt werden könnten. Bei kleinen Datenmengen, die im Konstruktor leicht verfügbar sind, ist dies kein Problem. Wenn Sie jedoch einige Daten berechnen müssen, bevor sie in der Instanz verfügbar sind, möchten Sie diese Gebühr möglicherweise nicht im Voraus bezahlen. Betrachten Sie beispielsweise diese Klasse:

Klasse MeineKlasse {
    Konstruktor() {
        this.data = eine teure Berechnung();
    }
}

Hier wird data Dateneigenschaft als Ergebnis der Durchführung einiger aufwändiger Berechnungen erstellt. Wenn Sie nicht sicher sind, ob die Immobilie genutzt wird, ist es möglicherweise nicht effizient, diese Berechnung im Voraus durchzuführen. Glücklicherweise gibt es mehrere Möglichkeiten, diese Aktionen auf einen späteren Zeitpunkt zu verschieben.

2. On-Demand-Attributmodus

Die einfachste Möglichkeit, die Ausführung einer aufwändigen Operation zu optimieren, besteht darin, mit der Berechnung zu warten, bis die Daten benötigt werden. Sie können beispielsweise eine Accessor-Eigenschaft mit einem Getter verwenden, um die Berechnung bei Bedarf wie folgt durchzuführen:

Klasse MeineKlasse {
    Daten abrufen() {
        returniere eine teure Berechnung();
    }
}

In diesem Fall wird Ihre aufwändige Berechnung erst durchgeführt, wenn jemand dieses data zum ersten Mal liest, was eine Verbesserung darstellt. Allerdings wird bei jedem Lesen data dieselbe aufwändige Berechnung durchgeführt, was schlimmer ist als im vorherigen Beispiel, wo die Berechnung zumindest nur einmal durchgeführt wurde. Dies ist keine gute Lösung, aber Sie können darauf aufbauend eine bessere schaffen.

3. Unordentliches Lazy-Loading-Attributmuster

Ein guter Anfang ist, Berechnungen nur durchzuführen, wenn auf eine Eigenschaft zugegriffen wird. Was Sie wirklich wollen, ist, die Informationen nach diesem Punkt zwischenzuspeichern und nur die zwischengespeicherte Version zu verwenden. Aber wo speichern Sie diese Informationen zwischen, um leicht darauf zugreifen zu können? Der einfachste Weg hierfür besteht darin, eine gleichnamige Eigenschaft zu definieren und ihren Wert auf die berechneten Daten festzulegen, und zwar wie folgt:

Klasse MeineKlasse {
    Daten abrufen() {
        const actualData = einigeExpensiveComputation();
 
        Objekt.defineProperty(diese, "Daten", {
            Wert: tatsächlicheDaten,
            beschreibbar: false,
            konfigurierbar: false,
            aufzählbar: falsch
        });
 
        tatsächliche Daten zurückgeben;
    }
}

Hier wird die data erneut als Getter für die Klasse definiert, dieses Mal wird das Ergebnis jedoch zwischengespeichert. Durch den Aufruf von Object.defineProperty() wird eine neue Eigenschaft namens data erstellt, die einen festen Wert actualData hat und so eingestellt ist, dass sie nicht beschreibbar, konfigurierbar und nicht aufzählbar ist (entsprechend dem Getter). Anschließend wird der Wert selbst zurückgegeben. Wenn data das nächste Mal auf die Eigenschaft zugreift, liest es aus der neu erstellten Eigenschaft, anstatt den Getter aufzurufen:

const-Objekt = neue MyClass();
 
// ruft den Getter auf
const data1 = Objekt.Daten;
 
// liest aus der Dateneigenschaft
const data2 = Objekt.Daten;

Tatsächlich werden alle Berechnungen nur beim ersten Lesen data durchgeführt. Bei jedem nachfolgenden Lesen data Dateneigenschaft wird die zwischengespeicherte Version zurückgegeben.

Ein Nachteil dieses Musters besteht darin, dass data als nicht aufzählbare Prototypeigenschaften beginnen und als nicht aufzählbare eigene Eigenschaften enden:

const-Objekt = neue MyClass();
console.log(object.hasOwnProperty("data")); // falsch
 
const data = Objekt.data;
console.log(Objekt.hasOwnProperty("Daten")); // wahr

Obwohl dieser Unterschied in vielen Fällen keine Rolle spielt, ist es wichtig, dieses Muster zu verstehen, da es bei der Weitergabe von Objekten zu subtilen Problemen führen kann. Glücklicherweise lässt sich dies mit einem aktualisierten Modell leicht beheben.

4. Einziger Lazy-Loading-Attributmodus der Klasse

Wenn Sie einen Anwendungsfall haben, bei dem es wichtig ist, dass die Lazy-Loading-Eigenschaft immer in der Instanz vorhanden ist, können Sie die Eigenschaft im Klassenkonstruktor mit Object.defineProperty() erstellen. Es ist etwas komplizierter als das vorherige Beispiel, stellt aber sicher, dass die Eigenschaft nur auf der Instanz vorhanden ist. Hier ist ein Beispiel:

Klasse MeineKlasse {
    Konstruktor() {

        Objekt.defineProperty(diese, "Daten", {
            erhalten() {
                const actualData = einigeExpensiveComputation();

                Objekt.defineProperty(diese, "Daten", {
                    Wert: tatsächlicheDaten,
                    beschreibbar: false,
                    konfigurierbar: false
                });

                tatsächliche Daten zurückgeben;
            },
            konfigurierbar: true,
            aufzählbar: wahr
        });

    }
}

Hier verwendet der Konstruktor data Object.defineProperty() . Die Eigenschaft wird auf der Instanz erstellt (mithilfe von this ), definiert einen Getter und gibt an, dass die Eigenschaft aufzählbar und konfigurierbar ist (typisch für eigene Eigenschaften). Es ist insbesondere wichtig, data konfigurierbar zu machen, damit Sie Object.defineProperty() erneut darauf aufrufen können.

Anschließend führt die Getter-Funktion die Berechnung durch und ruft Object.defineProperty() erneut auf. Das data wird jetzt als Datenattribut mit einem bestimmten Wert neu definiert und ist nicht beschreibbar und nicht konfigurierbar, um die endgültigen Daten zu schützen. Die berechneten Daten werden dann vom Getter zurückgegeben. Beim nächsten Lesen data Dateneigenschaft wird der gespeicherte Wert gelesen. Als Bonus existiert die data jetzt nur als eigene Eigenschaft und verhält sich vor und nach dem ersten Lesen gleich:

const-Objekt = neue MyClass();
console.log(Objekt.hasOwnProperty("Daten")); // wahr
 
const data = Objekt.data;
console.log(Objekt.hasOwnProperty("Daten")); // wahr

Für Klassen ist dies höchstwahrscheinlich das Muster, das Sie verwenden möchten. Objektliterale ermöglichen dagegen einen einfacheren Ansatz.

5. Muster der Lazy-Loading-Eigenschaft für Objektliterale

Wenn Sie ein Objektliteral anstelle einer Klasse verwenden, ist der Vorgang wesentlich einfacher, da für ein Objektliteral definierte Getter genau wie Dateneigenschaften als aufzählbare eigene Eigenschaften (und nicht als Prototypeigenschaften) definiert werden. Dies bedeutet, dass Sie das chaotische Lazy-Loading-Eigenschaftsmuster für Klassen verwenden können, ohne dass es für Objekte chaotisch wird:

const Objekt = {
    Daten abrufen() {
        const actualData = einigeExpensiveComputation();
 
        Objekt.defineProperty(diese, "Daten", {
            Wert: tatsächlicheDaten,
            beschreibbar: false,
            konfigurierbar: false,
            aufzählbar: falsch
        });
 
        tatsächliche Daten zurückgeben;
    }
};
 
console.log(Objekt.hasOwnProperty("Daten")); // wahr
 
const data = Objekt.data;
console.log(Objekt.hasOwnProperty("Daten")); // wahr

VI. Fazit

Die Möglichkeit, Objekteigenschaften in JavaScript neu zu definieren, bietet eine einzigartige Gelegenheit, Informationen zwischenzuspeichern, deren Berechnung möglicherweise teuer wäre. Indem Sie mit als Dateneigenschaften neu definierten Accessor-Eigenschaften beginnen, können Sie die Berechnung bis zum ersten Lesen der Eigenschaft verschieben und das Ergebnis dann zur späteren Verwendung zwischenspeichern. Dieser Ansatz funktioniert sowohl für Klassen als auch für Objektliterale und ist bei Objektliteralen etwas einfacher, da Sie sich keine Sorgen machen müssen, dass Ihre Getter auf dem Prototyp landen.

Eine der besten Möglichkeiten zur Leistungssteigerung besteht darin, die wiederholte Ausführung derselben Arbeit zu vermeiden. So können Sie Ihr Programm jederzeit beschleunigen, wenn Sie Ergebnisse zur späteren Verwendung zwischenspeichern können. Techniken wie das Lazy-Loading-Eigenschaftsmuster ermöglichen es, jede Eigenschaft zu einer Caching-Schicht zu machen und so die Leistung zu verbessern.

Oben finden Sie eine kurze Erläuterung der Details des Lazy-Loading-Attributmodus in JavaScript. Weitere Informationen zum JS-Lazy-Loading-Attributmodus finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung mehrerer Methoden zur Implementierung verzögerten Ladens in js
  • Synchrone, asynchrone und verzögerte Lademethoden von JS
  • Beispielcode für den Ladeeffekt von js-Bildern (verzögertes Laden + Wasserfallladen)
  • Mehrere Methoden zum Implementieren von verzögertem Laden in js
  • Drei Möglichkeiten zum Implementieren des Lazy Loading von JS-Bildern
  • Eine einfache Methode zum Implementieren verzögerter Lade- und Ein- und Ausblendeffekte von Bildern mit JS
  • ECHO.js Beispielcode für leichtes Lazy Loading in reinem JavaScript
  • Echo.js, eine JavaScript-Bibliothek zum verzögerten Laden von Bildern
  • So verwenden Sie das JQuery-Plugin zum Lazy Loading von Bildern jquery.lazyload.js
  • So verwenden Sie das jQuery-Plugin lazyload.js, um das Laden von Bildern zu verzögern

<<:  Erläuterung der Verwendung von GROUP BY in gruppierten Abfragen und der SQL-Ausführungsreihenfolge

>>:  Teilen Sie das Problem, dass Ubuntu 19 die Docker-Quelle nicht installieren kann

Artikel empfehlen

Beispiele für die Verwendung der MySQL-EXPLAIN-Anweisung

Inhaltsverzeichnis 1. Nutzung 2. Ausgabeergebniss...

Flex-Layout ermöglicht adaptive Seiten (Syntax und Beispiele)

Einführung in Flex Layout Flex bedeutet auf Engli...

Lösung für das Problem des verstümmelten Codes in MySQL 5.x

MySQL ist eine häufig verwendete Open-Source-Date...

7 coole dynamische Website-Designs zur Inspiration

Im Bereich Design gibt es jedes Jahr unterschiedl...

Hinweise zu Linux-Systembefehlen

Dieser Artikel beschreibt die Linux-Systembefehle...

Docker-Reinigungskiller/Docker-Overlay-Datei nimmt zu viel Speicherplatz ein

[Wenn ich mir all die Migrationsdateien im Intern...

CSS zum Erzielen des Bildschwebens mit der Maus-Falteffekts

CSS zum Erzielen des Bildschwebens mit der Maus-F...

Holen Sie sich die IP und den Hostnamen aller Hosts auf Zabbix

zabbix Zabbix ([`zæbiks]) ist eine Open-Source-Lö...

Beispiel für einen reinen CSS3-Mindmap-Stil

Mindmap Er sieht wahrscheinlich so aus: Die meist...

Vorteile und Nachteile des MySQL Advanced Learning Index sowie Nutzungsregeln

1. Vor- und Nachteile von Indizes Vorteile: schne...