Das Lazy-Loading-Attributmuster in JavaScript verstehen

Das Lazy-Loading-Attributmuster in JavaScript verstehen

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.

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.

Unordentliches Lazy-Loading-Eigenschaftsmuster

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.

Muster für Lazy-Loading-Eigenschaften einer 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.

Objektliteral-Lazy-Loading-Eigenschaftsmuster

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

abschließend

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 sind die Details des Lazy-Loading-Attributmodus in JavaScript aufgeführt. Weitere Informationen zu den Lazy-Loading-Attributen von JS 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
  • Beispiel für die Implementierung des verzögerten Ladens von Bildern, die nicht auf dem ersten Bildschirm angezeigt werden, mithilfe von JS
  • js, um einen verzögerten Ladeeffekt mehrerer Bilder zu erzielen
  • Mehrere Methoden zum Implementieren von verzögertem Laden in js

<<:  Erfahren Sie in zehn Minuten, wie Sie Microservices mit Docker bereitstellen

>>:  Erläuterung der MySQL-Transaktionsauswahl für die Aktualisierung und Datenkonsistenzverarbeitung

Artikel empfehlen

Erstellen Sie eine virtuelle Umgebung mit venv in Python3 in Ubuntu

1. Virtuelle Umgebung folgt dem Projekt, erstelle...

Grundlegende Verwendung von benutzerdefinierten Anweisungen in Vue

Inhaltsverzeichnis Vorwort Text 1. Globale Regist...

Beispiel für die Konvertierung von Webpack-Bildern in Base64

URL-Loader herunterladen yarn add -D URL-Lader Mo...

Detaillierte Erklärung der Anzeigeeigenschaft im CSS-Beschriftungsmodus

Der Code sieht folgendermaßen aus: <!DOCTYPE h...

Javascript-Countdown-Eingabeaufforderungsfeld

In diesem Artikelbeispiel wird der spezifische Ja...

CSS-Anfänger-Tutorial: Hintergrundbild füllt den gesamten Bildschirm

Wenn Sie möchten, dass die gesamte Benutzeroberfl...

Grafisches Tutorial zur Installation von MySQL 5.5.27

1. Installation von MySQL 1. Öffnen Sie die herun...

Beispiele für die Verwendung des Li-Tags in HTML

Ich möchte den Titel links und das Datum rechts a...

Detaillierte Erklärung der Mixins in Vue.js

Mixins stellen auf flexible Weise verteilte, wied...

So erstellen Sie eine Vue3-Desktopanwendung

In diesem Artikel sehen wir uns an, wie man mit V...

Interpretation des Moduls zum Lastenausgleich mit nginx

Inhaltsverzeichnis Zwei Module zur Verwendung von...