7619 Stimmen

Wie funktionieren die JavaScript-Schließungen?

Wie würden Sie JavaScript-Schließungen jemandem erklären, der zwar die Konzepte kennt, aus denen sie bestehen (z. B. Funktionen, Variablen und Ähnliches), aber die Schließungen selbst nicht versteht?

Ich habe gesehen das Beispiel Schema auf Wikipedia angegeben, aber leider hat es nicht geholfen.

43voto

Dinesh Kanivu Punkte 2484

Ich bevorzuge kürzere Erklärungen, siehe daher das folgende Bild.

Enter image description here

function f1() > Hellrote Box

function f2() > Rote kleine Box

Hier haben wir zwei Funktionen, f1() y f2() . f2() ist innerlich zu f1(). f1() hat eine Variable, var x = 10 .

Beim Aufrufen der Funktion f1() , f2() kann auf den Wert von var x = 10 .

Hier ist der Code:

function f1() {
    var x=10;

    function f2() {
        console.log(x)
    }

    return f2

}
f1()

f1() hier aufzurufen:

Enter image description here

39voto

Shushanth Pallegar Punkte 2714

In JavaScript sind Closures großartig und einzigartig, da Variablen oder Argumente für innere Funktionen zur Verfügung stehen und auch dann noch vorhanden sind, wenn die äußere Funktion zurückgekehrt ist. Closures werden in den meisten Entwurfsmustern in JS verwendet

function getFullName(a, b) {
  return a + b;
}

function makeFullName(fn) {

  return function(firstName) {

    return function(secondName) {

      return fn(firstName, secondName);

    }
  }
}

makeFullName(getFullName)("Stack")("overflow"); // Stackoverflow

37voto

Alireza Punkte 92209

Eine Closure ist eine Funktion, die Zugriff auf den übergeordneten Bereich hat, auch nachdem die übergeordnete Funktion geschlossen wurde.

Ein Abschluss ist also eine Funktion einer anderen Funktion. Wir können sagen, wie eine Kindfunktion.

Ein Abschluss ist eine innere Funktion, die Zugriff auf die äußere (einschließenden) Funktion hat. Die Closure hat drei Bereichsketten: Sie hat Zugriff auf ihren eigenen Bereich (Variablen, die zwischen den geschweiften Klammern), sie hat Zugriff auf den Bereich der äußeren Funktion Variablen der äußeren Funktion, und sie hat Zugriff auf die globalen Variablen.

Die innere Funktion hat nicht nur Zugriff auf die äußere Funktion Variablen, sondern auch auf die Parameter der äußeren Funktion. Beachten Sie, dass die innere Funktion nicht das Argumente-Objekt der äußeren Funktion aufrufen kann, aufrufen kann, auch wenn sie die Parameter der äußeren Funktion aufrufen kann direkt aufrufen kann.

Sie erstellen einen Abschluss, indem Sie eine Funktion innerhalb einer anderen Funktion hinzufügen.

Außerdem ist es eine sehr nützliche Methode, die in vielen bekannten Frameworks verwendet wird, darunter Angular , Node.js y jQuery :

Closures werden in Node.js ausgiebig verwendet; sie sind die Arbeitspferde der Node.js' asynchroner, nicht-blockierender Architektur. Closures sind auch häufig in jQuery und so ziemlich jedem Stück JavaScript-Code, das Sie lesen Code, den Sie lesen.

Aber wie sehen die Verschlüsse in einer realen Kodierung aus? Sehen Sie sich diesen einfachen Beispielcode an:

function showName(firstName, lastName) {
      var nameIntro = "Your name is ";
      // this inner function has access to the outer function's variables, including the parameter
      function makeFullName() {
          return nameIntro + firstName + " " + lastName;
      }
      return makeFullName();
  }

  console.log(showName("Michael", "Jackson")); // Your name is Michael Jackson

Auch dies ist klassisch Schließung Weg in jQuery, die jeder Javascript und jQuery Entwickler verwendet es eine Menge:

$(function() {
    var selections = [];
    $(".niners").click(function() { // this closure has access to the selections variable
        selections.push(this.prop("name")); // update the selections variable in the outer function's scope
    });
});

Aber warum verwenden wir Schließungen? Wann verwenden wir sie in einer tatsächlichen Programmierung? Was ist der praktische Nutzen von Closures? Im Folgenden finden Sie eine gute Erklärung und ein Beispiel von MDN:

Praktische Verschlüsse

Closures sind nützlich, weil sie es Ihnen ermöglichen, einige Daten (die lexikalischen Umgebung) mit einer Funktion verbinden können, die diese Daten bearbeitet. Diese hat offensichtliche Parallelen zur objektorientierten Programmierung, wo Objekte Objekte die Möglichkeit bieten, einige Daten (die Eigenschaften des Objekts) mit einer oder mehreren mehreren Methoden zu verknüpfen.

Daher können Sie einen Verschluss überall dort verwenden, wo Sie normalerweise ein Objekt mit nur einer einzigen Methode verwenden.

Situationen, in denen Sie dies tun sollten, sind besonders häufig bei dem Web. Ein Großteil des Codes, den wir in Front-End-JavaScript schreiben, ist ereignisbasiert - wir definieren ein bestimmtes Verhalten und binden es dann an ein Ereignis, das das vom Benutzer ausgelöst wird (z. B. ein Klick oder ein Tastendruck). Unser Code ist in der Regel als Callback angehängt: eine einzelne Funktion, die als Reaktion auf das Ereignis ausgeführt wird.

Nehmen wir zum Beispiel an, wir möchten einer Seite einige Schaltflächen hinzufügen, die die Textgröße anpassen. Eine Möglichkeit, dies zu tun, ist die Angabe der font-size des body-Elements in Pixeln anzugeben und dann die Größe der anderen Elemente auf der Seite (z. B. Überschriften) mit der relativen em Einheit:

Lesen Sie den nachstehenden Code und führen Sie ihn aus, um zu sehen, wie die Schließung uns dabei hilft, auf einfache Weise separate Funktionen für die einzelnen Abschnitte zu erstellen:

//javascript
function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;

/*css*/
body {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 12px;
}

h1 {
  font-size: 1.5em;
}

h2 {
  font-size: 1.2em;
}

<!--html><!-->
<p>Some paragraph text</p>
<h1>some heading 1 text</h1>
<h2>some heading 2 text</h2>

<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>

Für weitere Studien über Schließungen empfehle ich Ihnen diese Seite von MDN: https://developer.mozilla.org/en/docs/Web/JavaScript/Closures

30voto

Charlie Punkte 3985

Für einen Sechsjährigen?

Sie und Ihre Familie leben in der mythischen Stadt Ann Ville. Du hast einen Freund, der nebenan wohnt, also rufst du ihn an und bittest ihn, zum Spielen rauszukommen. Du wählst:

000001 (jamiesHouse)

Nach einem Monat ziehen Sie und Ihre Familie aus Ann Ville in die nächste Stadt, aber Sie und Ihr Freund bleiben in Kontakt. Jetzt müssen Sie die Vorwahl der Stadt wählen, in der Ihr Freund lebt, bevor Sie seine "richtige" Nummer wählen:

001 000001 (annVille.jamiesHouse)

Ein Jahr später ziehen deine Eltern in ein ganz anderes Land, aber du und dein Freund bleiben in Kontakt, und nachdem du deine Eltern genervt hast, dass du zum Auslandstarif telefonieren darfst, wählst du jetzt:

01 001 000001 (myOldCountry.annVille.jamiesHouse)

Seltsamerweise ziehen Sie und Ihre Familie nach dem Umzug in Ihr neues Land zufällig in eine neue Stadt namens Ann Ville... und Sie freunden sich zufällig mit einer neuen Person namens Jamie an... Du rufst sie an...

000001 (jamiesHouse)

Unheimlich...

So unheimlich, dass du Jamie aus deiner alten Heimat davon erzählst... Sie lachen viel darüber. Eines Tages machen Sie und Ihre Familie Urlaub in der alten Heimat. Du besuchst deine alte Stadt (Ann Ville) und gehst Jamie besuchen...

  • "Wirklich? Noch ein Jamie? In Ann Ville? In deinem neuen Land!!?"
  • "Ja... Rufen wir sie an..."

02 001 000001 (myNewCountry.annVille.jamiesHouse)

Stellungnahmen?

Außerdem habe ich eine Menge Fragen über die Geduld eines modernen Sechsjährigen...

28voto

Mayur Randive Punkte 611

Hier ist ein einfaches Echtzeit-Szenario. Lesen Sie es sich einfach durch und Sie werden verstehen, wie wir hier die Schließung verwendet haben (sehen Sie, wie sich die Sitzplatznummer ändert).

Auch alle anderen zuvor erläuterten Beispiele sind sehr gut geeignet, um das Konzept zu verstehen.

function movieBooking(movieName) {
    var bookedSeatCount = 0;
    return function(name) {
        ++bookedSeatCount ;
        alert( name + " - " + movieName + ", Seat - " + bookedSeatCount )
    };
};

var MI1 = movieBooking("Mission Impossible 1 ");
var MI2 = movieBooking("Mission Impossible 2 ");

MI1("Mayur");
// alert
// Mayur - Mission Impossible 1, Seat - 1

MI1("Raju");
// alert
// Raju - Mission Impossible 1, Seat - 2

MI2("Priyanka");
// alert
// Raja - Mission Impossible 2, Seat - 1

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X