JavaScript lexikalischer Umfang und Abschluss



Übersetzung der JavaScript-Umgebung, Lexical Scope und Closures .

Sprechen wir über die Umwelt. Unser riesiger Planet ist einer für alle. Während des Baus einer neuen Chemiefabrik wäre es schön, diese zu isolieren, damit nicht alle internen Prozesse ihre Grenzen verlassen. Wir können sagen, dass die Umwelt und das Mikroklima dieser Pflanze von der äußeren Umgebung isoliert sind.

Das Programm ist ähnlich angeordnet. Was Sie extern erstellen - externe Funktionen, bedingte Anweisungen, Schleifen und andere Blöcke - ist eine externe, globale Umgebung.



Das konstante age , die multiplier und die result befinden sich in der externen Umgebung. Diese Komponenten haben einen globalen Geltungsbereich. Ein Bereich ist der Bereich, in dem eine Komponente verfügbar ist.

In diesem Fall ist x eine Konstante innerhalb der multiplier . Da es sich in einem Codeblock befindet, ist es eine lokale Konstante, keine globale. Es ist nur innerhalb der Funktion sichtbar, aber nicht außerhalb - sein Gültigkeitsbereich ist lokal.

Die multiplier hat eine weitere Komponente aus dem lokalen Bereich - dies ist das Argument num . Die Definition ist schwieriger als eine Konstante oder Variable, verhält sich jedoch ungefähr wie eine lokale Variable.

Wir haben keinen externen Zugriff auf x - es scheint nicht zu existieren:



console.log heißt x in einer globalen Umgebung, in der es nicht definiert ist. Als Ergebnis haben wir einen ReferenceError erhalten.

Wir können x global setzen:



Wir haben ein globales x mit einem bekannten Wert, aber das lokale x in der multiplier ist nur von innen sichtbar. Diese x sind in keiner Weise verbunden - sie befinden sich in unterschiedlichen Umgebungen. Trotz des gleichen Namens mischen sie sich nicht.

Jeder Codeblock in geschweiften Klammern wird zu einer lokalen Umgebung. Hier ist ein Beispiel für die Verwendung von if :



Das gleiche passiert mit while und for Schleifen.

Lokal bedeutet also von außen unsichtbar. Das heißt, global ist überall sichtbar, sogar innerhalb von Objekten? Ja!



Die globale Variable a hat sich innerhalb der changer geändert. Die Funktion wird nur beim Aufruf wirksam, nicht beim Definieren, daher ist zunächst a=0 , und beim Aufruf nimmt der changer den Wert 1 .

Es ist leicht, der Versuchung zu erliegen und alles in einen globalen Rahmen zu stellen, wobei man die Komplexität einzelner Umgebungen vergisst - aber das ist eine schreckliche Idee. Globale Variablen machen Ihren Code extrem zerbrechlich. Jedes Element kann jederzeit jedes andere beschädigen. Verwenden Sie daher nicht den globalen Bereich und behalten Sie alles bei.

Teil II Lexikalischer Bereich


Schauen Sie sich dieses Programm an:



Die multiplier gibt die Ergebnisse der Multiplikation a und b . a intern angegeben, b nicht.

Beim Versuch, die a*b Multiplikationsoperation auszuführen, sucht JavaScript nach den Werten von a und b . Er beginnt drinnen zu suchen und geht dann nach draußen, um einen Bereich nach dem anderen zu studieren, bis er findet, wonach er gesucht hat, oder nicht versteht, dass es unmöglich ist, ihn zu finden.

Daher sucht JavaScript in diesem Beispiel nach a innerhalb des lokalen Bereichs - innerhalb der multiplier . Er findet sofort den Wert und geht zu b . b er wird nicht in der lokalen Umgebung finden, also geht er darüber hinaus. Dort erfährt er, dass b 10 . Aus a*b wird also 5*10 und dann 50 .

Dieser Code könnte sich in einer anderen Funktion befinden, die sich auch in einer anderen Funktion befindet. Ohne b in der ersten Ebene zu finden, würde JavaScript immer weiter nach allem in neuen und neuen Ebenen suchen.

Bitte beachten Sie, dass a=7 das Ergebnis von Berechnungen in keiner Weise beeinflusst: Der Wert von a wurde im Inneren gefunden, daher spielt das externe a keine Rolle.

Dies wird als lexikalischer Bereich bezeichnet. Der Umfang einer Komponente wird durch die Position dieser Komponente im Code bestimmt, und verschachtelte Blöcke haben Zugriff auf externe Bereiche.

Teil III. Kurzschlüsse


Umgebungen und Bereiche werden von den meisten Programmiersprachen unterstützt, und dieser Mechanismus ermöglicht die Einführung von Schließungen. Closure ist von Natur aus eine Funktion, die sich an intern verwendete externe Entitäten „erinnert“.

Bevor wir fortfahren, erinnern wir uns daran, wie Funktionen erstellt und verwendet werden:



f ist eine ziemlich nutzlose Funktion, die immer 0 zurückgibt. Das Set besteht aus zwei Teilen - einer Konstanten und der Funktion selbst.

Es ist wichtig zu beachten, dass dies separate Komponenten sind. Die erste Komponente ist eine Konstante namens f . Sein Wert kann eine Zahl oder ein Zeichenfolgenwert sein. In diesem Fall ist der Wert eine Funktion.

In früheren Lektionen haben wir eine Analogie zitiert: Konstanten sind wie Blätter mit einem Namen auf der einen Seite und einem Wert auf der anderen Seite. Somit ist f ein Stück Papier mit f auf der einen Seite und einer Beschreibung der Funktion, die auf der anderen Seite gestartet wird.

Beim Aufruf dieser Funktion:



Basierend auf der Beschreibung eines Blattes Papier wird eine neue „Box“ erstellt.

Zurück zu den Verschlüssen. Hier ist ein Beispielcode.



Die Funktion createPrinter erstellt eine name und anschließend eine Funktion namens printName . Beide sind lokal für die Funktion createPrinter und nur innerhalb dieser Funktion verfügbar.

printName selbst hat printName lokalen Komponenten, aber es besteht Zugriff auf den Bereich, in dem es erstellt wurde, und auf die externe Umgebung, in der der Konstante ein name zugewiesen wird.

Die Funktion createPrinter gibt die Funktion createPrinter zurück. Denken Sie daran, dass Funktionsdefinitionen Beschreibungen laufender Funktionen sind, sondern nur Datenelemente wie Zahlen oder Ketten. Daher können wir die Definition einer Funktion genauso zurückgeben wie Zahlen.

Im äußeren Bereich erstellen wir die Konstante myPrinter und setzen den Rückgabewert als createPrinter . Eine Funktion wird zurückgegeben, sodass myPrinter auch zu einer Funktion wird. Wenn Sie es anrufen, erscheint King auf dem Bildschirm.

Hier ist das Lustige: Die name wurde in der Funktion createPrinter . Die Funktion wurde aufgerufen und ausgeführt. Wie Sie wissen, existiert eine Funktion nach Beendigung ihrer Arbeit nicht mehr. Die magische Box verschwindet zusammen mit dem gesamten Inhalt.

Aber er gab eine andere Funktion zurück, die sich irgendwie an die name erinnerte. Beim Aufruf von myPrinter wir also King - den Wert, an den sich die Funktion erinnert, obwohl dieser Bereich nicht mehr existiert.

Die von createPrinter Funktion wird als Abschluss bezeichnet. Ein Abschluss ist eine Kombination aus einer Funktion und der Umgebung, in der sie definiert wurde. Die Funktion "schloss" in sich bestimmte Informationen ein, die im Bereich empfangen wurden.

Dies mag wie eine seltsame Eigenart von JavaScript erscheinen, aber die kluge Verwendung von Verschlüssen kann dazu beitragen, Ihren Code angenehmer, sauberer und lesbarer zu machen. Das Prinzip der Rückgabe von Funktionen wie die Rückgabe von Zahlen und Zeichenfolgenwerten gibt Ihnen mehr Handlungsspielraum.

Source: https://habr.com/ru/post/de460861/


All Articles