Ich versuche mein Bestes, um mich mit JavaScript-Verschlüssen zu beschäftigen.
Ich erhalte das durch die Rückgabe einer inneren Funktion, die Zugriff auf jede Variable hat, die in ihrem unmittelbaren übergeordneten Element definiert ist.
Wo wäre das für mich nützlich? Vielleicht habe ich es noch nicht ganz verstanden. Die meisten Beispiele, die ich online gesehen habe, enthalten keinen realen Code, sondern nur vage Beispiele.
Kann mir jemand eine reale Verwendung eines Verschlusses zeigen?
Ist das zum Beispiel?
var warnUser = function (msg) {
var calledCount = 0;
return function() {
calledCount++;
alert(msg + '\nYou have been warned ' + calledCount + ' times.');
};
};
var warnForTamper = warnUser('You can not tamper with our HTML.');
warnForTamper();
warnForTamper();
Antworten:
Ich habe Verschlüsse verwendet, um Dinge zu tun wie:
Wie Sie dort sehen können,
a
befindet sich jetzt ein Objekt mit einer Methodepublicfunction
(a.publicfunction()
), die aufruftprivatefunction
und nur innerhalb des Abschlusses existiert. Sie können NICHTprivatefunction
direkt (dha.privatefunction()
) anrufen , nurpublicfunction()
.Es ist ein minimales Beispiel, aber vielleicht können Sie sehen, wie es verwendet wird? Wir haben dies verwendet, um öffentliche / private Methoden durchzusetzen.
quelle
Angenommen, Sie möchten zählen, wie oft der Benutzer auf einer Webseite auf eine Schaltfläche geklickt hat .
Dazu lösen Sie bei
onclick
Ereignis der Schaltfläche eine Funktion aus, um die Anzahl der Variablen zu aktualisierenJetzt könnte es viele Ansätze geben wie:
1) Sie können eine globale Variable und eine Funktion verwenden, um den Zähler zu erhöhen :
Die Gefahr besteht jedoch darin, dass jedes Skript auf der Seite den Zähler ändern kann, ohne ihn aufzurufen
updateClickCount()
.2) Nun könnten Sie daran denken, die Variable innerhalb der Funktion zu deklarieren:
Aber hey! Bei jedem
updateClickCount()
Aufruf der Funktion wird der Zähler erneut auf 1 gesetzt.3) Denken Sie über verschachtelte Funktionen nach ?
Verschachtelte Funktionen haben Zugriff auf den Bereich "über" ihnen.
In diesem Beispiel hat die innere Funktion
updateClickCount()
Zugriff auf die Zählervariable in der übergeordneten FunktioncountWrapper()
Dies hätte das Gegendilemma lösen können, wenn Sie die
updateClickCount()
Funktion von außen erreichen könnten und auch einen Weg finden müssten,counter = 0
nur einmal und nicht jedes Mal auszuführen.4) Schließung zur Rettung! (selbstaufrufende Funktion) :
Die selbstaufrufende Funktion wird nur einmal ausgeführt. Es setzt den
counter
Wert auf Null (0) und gibt einen Funktionsausdruck zurück.Dieser Weg
updateClickCount
wird zur Funktion. Der "wunderbare" Teil ist, dass es auf den Zähler im übergeordneten Bereich zugreifen kann.Dies wird als JavaScript-Schließung bezeichnet . Es ermöglicht einer Funktion, " private " Variablen zu haben.
Das
counter
ist durch den Umfang der anonymen Funktion geschützt und kann nur mit der Funktion add geändert werden!Lebhafteres Beispiel für Closure:
Referenz: https://www.w3schools.com/js/js_function_closures.asp
quelle
Das Beispiel, das Sie geben, ist ausgezeichnet. Verschlüsse sind ein Abstraktionsmechanismus, mit dem Sie Bedenken sehr sauber trennen können. In Ihrem Beispiel wird die Instrumentierung (Zählen von Aufrufen) von der Semantik (eine API zur Fehlerberichterstattung) getrennt. Andere Verwendungen umfassen:
Parametrisiertes Verhalten an einen Algorithmus übergeben (klassische Programmierung höherer Ordnung):
Simulation der objektorientierten Programmierung:
Implementierung einer exotischen Flusskontrolle wie der Ereignisbehandlung von jQuery und AJAX-APIs.
quelle
int
?) Als ich das letzte Mal nachgesehen habe, war JavaScript eine Sprache vom Typ Ente. Vielleicht haben Sie an Java gedacht?Ich weiß, dass ich diese Frage sehr spät beantworte, aber es könnte jedem helfen, der 2018 noch nach der Antwort sucht.
Javascript-Verschlüsse können verwendet werden, um Drossel- und Entprellungsfunktionen in Ihrer Anwendung zu implementieren .
Drosselung :
Durch die Drosselung wird begrenzt, wie oft eine Funktion im Laufe der Zeit maximal aufgerufen werden kann. Wie in "Führen Sie diese Funktion höchstens einmal alle 100 Millisekunden aus."
Code:
Entprellen :
Durch das Entprellen wird eine Funktion begrenzt, die erst nach einer bestimmten Zeit wieder aufgerufen wird, ohne dass sie aufgerufen wird. Wie in "Führen Sie diese Funktion nur aus, wenn 100 Millisekunden vergangen sind, ohne dass sie aufgerufen wurde."
Code:
Wie Sie sehen können, haben Schließungen bei der Implementierung von zwei schönen Funktionen geholfen, die jede Web-App haben sollte, um eine reibungslose Benutzeroberfläche zu bieten.
Ich hoffe es wird jemandem helfen.
quelle
Ja, das ist ein gutes Beispiel für einen nützlichen Verschluss. Der Aufruf von warnUser erstellt die
calledCount
Variable in ihrem Bereich und gibt eine anonyme Funktion zurück, die in derwarnForTamper
Variablen gespeichert ist. Da es immer noch einen Abschluss gibt, der die Variable "warnForTamper()
CalledCount" verwendet, wird sie beim Beenden der Funktion nicht gelöscht. Daher erhöht jeder Aufruf von die Variable "Scoped" den Gültigkeitsbereich und alarmiert den Wert.Das häufigste Problem, das ich bei StackOverflow sehe, ist, dass jemand die Verwendung einer Variablen "verzögern" möchte, die bei jeder Schleife erhöht wird. Da die Variable jedoch einen Gültigkeitsbereich hat, erfolgt jeder Verweis auf die Variable nach dem Ende der Schleife, was zu dem führt Endzustand der Variablen:
Dies würde dazu führen, dass jede Warnung den gleichen Wert anzeigt, den Wert
i
, auf den sie erhöht wurde, als die Schleife endete. Die Lösung besteht darin, einen neuen Abschluss zu erstellen, einen separaten Bereich für die Variable. Dies kann mithilfe einer sofort ausgeführten anonymen Funktion erfolgen, die die Variable empfängt und ihren Status als Argument speichert:quelle
Insbesondere in der JavaScript-Sprache (oder einer beliebigen ECMAScript-Sprache) sind Schließungen hilfreich, um die Implementierung von Funktionen zu verbergen und gleichzeitig die Benutzeroberfläche anzuzeigen.
Stellen Sie sich beispielsweise vor, Sie schreiben eine Klasse von Datumsdienstprogrammmethoden und möchten Benutzern ermöglichen, Wochentagsnamen nach Index zu suchen, aber nicht, dass sie das unter der Haube verwendete Namensarray ändern können.
Beachten Sie, dass das
days
Array einfach als Eigenschaft desdateUtil
Objekts gespeichert werden kann, dann aber für Benutzer des Skripts sichtbar ist und sie es sogar ändern können, wenn sie dies möchten, ohne dass Sie Ihren Quellcode benötigen. Da es jedoch von der anonymen Funktion eingeschlossen ist, die die Datumssuchfunktion zurückgibt, ist es nur für die Suchfunktion zugänglich, sodass es jetzt manipulationssicher ist.quelle
Es gibt einen Abschnitt über praktische Abschlüsse im Mozilla Developer Network .
quelle
return function ()...
Code entferne, der immer noch gut funktioniert. Die Schließung ist nicht notwendigEine weitere häufige Verwendung für Schließungen besteht darin,
this
eine Methode an ein bestimmtes Objekt zu binden , damit sie an anderer Stelle aufgerufen werden kann (z. B. als Ereignishandler).Immer wenn ein Mausbewegungsereignis ausgelöst wird,
watcher.follow(evt)
wird aufgerufen.Verschlüsse sind auch ein wesentlicher Bestandteil von Funktionen höherer Ordnung, was das sehr häufige Muster des Umschreibens mehrerer ähnlicher Funktionen als einzelne Funktion höherer Ordnung durch Parametrisierung der unterschiedlichen Teile ermöglicht. Als abstraktes Beispiel
wird
Dabei sind A und B keine syntaktischen Einheiten, sondern Quellcode-Zeichenfolgen (keine Zeichenfolgenliterale).
Ein konkretes Beispiel finden Sie unter " Optimieren meines Javascript mit einer Funktion ".
quelle
Hier habe ich einen Gruß, den ich mehrmals sagen möchte. Wenn ich einen Abschluss erstelle, kann ich diese Funktion einfach aufrufen, um die Begrüßung aufzuzeichnen. Wenn ich den Verschluss nicht erstelle, muss ich meinen Namen jedes Mal weitergeben.
Ohne Schließung ( https://jsfiddle.net/lukeschlangen/pw61qrow/3/ ):
Mit einer Schließung ( https://jsfiddle.net/lukeschlangen/Lb5cfve9/3/ ):
quelle
Wenn Sie mit dem Konzept vertraut sind, eine Klasse im objektorientierten Sinne zu instanziieren (dh ein Objekt dieser Klasse zu erstellen), sind Sie dem Verständnis von Abschlüssen nahe.
Stellen Sie sich das so vor: Wenn Sie zwei Personenobjekte instanziieren, wissen Sie, dass die Klassenmitgliedsvariable "Name" nicht von Instanzen gemeinsam genutzt wird. Jedes Objekt hat seine eigene 'Kopie'. Wenn Sie einen Abschluss erstellen, wird die freie Variable (in Ihrem obigen Beispiel 'CalledCount') an die 'Instanz' der Funktion gebunden.
Ich denke, Ihr konzeptioneller Sprung wird leicht durch die Tatsache behindert, dass jede Funktion / Schließung, die von der Funktion warnUser zurückgegeben wird (abgesehen davon, dass es sich um eine Funktion höherer Ordnung handelt ), "CalledCount" mit demselben Anfangswert (0) bindet, während dies häufig beim Erstellen von Schließungen der Fall ist Es ist sinnvoller, verschiedene Initialisierer an die Funktion höherer Ordnung zu übergeben, ähnlich wie verschiedene Werte an den Konstruktor einer Klasse übergeben werden.
Angenommen, 'CalledCount' erreicht einen bestimmten Wert, und Sie möchten die Sitzung des Benutzers beenden. Je nachdem, ob die Anfrage vom lokalen Netzwerk oder vom großen schlechten Internet eingeht, möchten Sie möglicherweise unterschiedliche Werte dafür (ja, es ist ein erfundenes Beispiel). Um dies zu erreichen, können Sie verschiedene Anfangswerte für aufgerufene Anzahl an warnUser übergeben (dh -3 oder 0?).
Ein Teil des Problems mit der Literatur ist die Nomenklatur, mit der sie beschrieben werden ("lexikalischer Umfang", "freie Variablen"). Lass dich nicht täuschen, Verschlüsse sind einfacher als es scheint ... auf den ersten Blick ;-)
quelle
Hier habe ich ein einfaches Beispiel für ein Schließungskonzept, das wir auf unserer E-Commerce-Website oder in vielen anderen verwenden können. Ich füge meinen jsfiddle-Link zum Beispiel hinzu. Es enthält eine kleine Produktliste mit 3 Artikeln und einen Warenkorb.
Jsfiddle
quelle
Verwendung von Verschlüssen:
Verschlüsse sind eine der leistungsstärksten Funktionen von JavaScript. JavaScript ermöglicht das Verschachteln von Funktionen und gewährt der inneren Funktion vollen Zugriff auf alle Variablen und Funktionen, die in der äußeren Funktion definiert sind (und auf alle anderen Variablen und Funktionen, auf die die äußere Funktion Zugriff hat). Die äußere Funktion hat jedoch keinen Zugriff auf die in der inneren Funktion definierten Variablen und Funktionen. Dies bietet eine Art Sicherheit für die Variablen der inneren Funktion. Da die innere Funktion Zugriff auf den Umfang der äußeren Funktion hat, leben die in der äußeren Funktion definierten Variablen und Funktionen länger als die äußere Funktion selbst, wenn es der inneren Funktion gelingt, über das Leben der äußeren Funktion hinaus zu überleben.
Beispiel:
Im obigen Code ist die Namensvariable der äußeren Funktion für die inneren Funktionen zugänglich, und es gibt keine andere Möglichkeit, auf die inneren Variablen zuzugreifen, als über die inneren Funktionen. Die inneren Variablen der inneren Funktion dienen als sichere Speicher für die inneren Funktionen. Sie enthalten "persistente" und dennoch sichere Daten, mit denen die inneren Funktionen arbeiten können. Die Funktionen müssen nicht einmal einer Variablen zugewiesen sein oder einen Namen haben. Lesen Sie hier für Details
quelle
Ich mag Mozillas Funktionsfactory- Beispiel .
quelle
Das JavaScript-Modulmuster verwendet Verschlüsse. Sein schönes Muster ermöglicht es Ihnen, etwas Ähnliches wie "öffentliche" und "private" Vars zu haben.
quelle
Ich habe vor einiger Zeit einen Artikel darüber geschrieben, wie Verschlüsse verwendet werden können, um den Code für die Ereignisbehandlung zu vereinfachen. Es vergleicht die ASP.NET-Ereignisbehandlung mit clientseitiger jQuery.
http://www.hackification.com/2009/02/20/closures-simplify-event-handling-code/
quelle
Dieser Thread hat mir sehr geholfen, besser zu verstehen, wie Verschlüsse funktionieren. Ich habe seitdem selbst experimentiert und mir diesen ziemlich einfachen Code ausgedacht, der einigen anderen Leuten helfen kann, zu sehen, wie Abschlüsse auf praktische Weise verwendet werden können und wie der Abschluss auf verschiedenen Ebenen verwendet wird, um statische und ähnliche Variablen beizubehalten / oder globale Variablen, ohne dass das Risiko besteht, dass sie überschrieben oder mit globalen Variablen verwechselt werden. Auf diese Weise werden die Schaltflächenklicks sowohl auf lokaler Ebene für jede einzelne Schaltfläche als auch auf globaler Ebene verfolgt, wobei jeder Schaltflächenklick gezählt wird, was zu einer einzelnen Zahl beiträgt. Hinweis: Ich habe dazu keine globalen Variablen verwendet. Dies ist der eigentliche Punkt der Übung. Ich habe einen Handler, der auf jede Schaltfläche angewendet werden kann, die auch global zu etwas beiträgt.
Bitte Experten, lassen Sie mich wissen, wenn ich hier schlechte Praktiken begangen habe! Ich lerne dieses Zeug immer noch selbst.
quelle
Referenz: Praktische Verwendung von Verschlüssen
In der Praxis können Verschlüsse elegante Designs erstellen, die die Anpassung verschiedener Berechnungen, verzögerter Anrufe, Rückrufe, die Erstellung eines gekapselten Bereichs usw. ermöglichen.
Ein Beispiel für die Sortiermethode von Arrays, die die Sortierbedingungsfunktion als Argument akzeptiert:
Zuordnen von Funktionalen als Zuordnungsmethode von Arrays, die ein neues Array anhand der Bedingung des Funktionsarguments abbildet:
Oft ist es zweckmäßig, Suchfunktionen mit funktionalen Argumenten zu implementieren, die nahezu unbegrenzte Suchbedingungen definieren:
Wir können auch feststellen, dass das Anwenden von Funktionalen beispielsweise eine forEach-Methode ist, die eine Funktion auf ein Array von Elementen anwendet:
Eine Funktion wird auf Argumente angewendet (auf eine Liste von Argumenten - in apply und auf positionierte Argumente - in call):
Zurückgestellte Anrufe:
Rückruffunktionen:
Erstellung eines gekapselten Bereichs zum Ausblenden von Hilfsobjekten:
quelle
Geige
quelle
Verschlüsse sind eine nützliche Methode zum Erstellen Generatoren, eine Sequenz, die bei Bedarf erhöht wird:
Die Unterschiede sind wie folgt zusammengefasst:
Verweise
quelle
Im angegebenen Beispiel ist der Wert der beiliegenden Variablen 'counter' geschützt und kann nur mit den angegebenen Funktionen (Inkrementieren, Dekrementieren) geändert werden. weil es in einem Verschluss ist,
quelle
Erklären der praktischen Verwendung für einen Abschluss in JavaScript ---
Wenn wir eine Funktion innerhalb einer anderen Funktion erstellen, erstellen wir einen Abschluss. Verschlüsse sind leistungsstark, da sie die Daten ihrer äußeren Funktionen lesen und bearbeiten können. Immer wenn eine Funktion aufgerufen wird, wird für diesen Aufruf ein neuer Bereich erstellt. Die in der Funktion deklarierte lokale Variable gehört zu diesem Bereich und kann nur von dieser Funktion aus aufgerufen werden. Wenn die Funktion die Ausführung beendet hat, wird der Bereich normalerweise zerstört.
Ein einfaches Beispiel für eine solche Funktion ist:
Im obigen Beispiel deklariert die Funktion buildName () eine Begrüßung einer lokalen Variablen und gibt sie zurück. Jeder Funktionsaufruf erstellt einen neuen Bereich mit einer neuen lokalen Variablen. Nachdem die Funktion ausgeführt wurde, können wir nicht mehr auf diesen Bereich verweisen, sodass der Müll gesammelt wird.
Aber wie wäre es, wenn wir einen Link zu diesem Bereich haben?
Schauen wir uns die nächste Funktion an:
Die Funktion sayName () aus diesem Beispiel ist ein Abschluss. Die Funktion sayName () verfügt über einen eigenen lokalen Bereich (mit variabler Begrüßung) und hat auch Zugriff auf den Bereich der äußeren (umschließenden) Funktion. In diesem Fall die Variable Begrüßung von buildName ().
Nachdem die Ausführung von buildName abgeschlossen ist, wird der Bereich in diesem Fall nicht zerstört. Die Funktion sayMyName () hat weiterhin Zugriff darauf, sodass kein Müll gesammelt wird. Es gibt jedoch keine andere Möglichkeit, auf Daten aus dem äußeren Bereich zuzugreifen, als das Schließen. Der Abschluss dient als Tor zwischen dem globalen Kontext und dem äußeren Bereich.
quelle
Ich versuche, Clousures zu lernen, und ich denke, ein Beispiel, das ich erstellt habe, ist ein praktischer Anwendungsfall. Sie können Snippet ausführen und das Ergebnis in der Konsole anzeigen. Wir haben zwei separate Benutzer, die separate Daten haben. Jeder von ihnen kann den aktuellen Status anzeigen und aktualisieren.
quelle