Verschachtelte JavaScript-Funktion

96

Ich habe einen Code für Javascript bekommen, den ich einfach nicht verstehe:

function dmy(d) {
    function pad2(n) {
        return (n < 10) ? '0' + n : n;
    }

    return pad2(d.getUTCDate()) + '/' +
       pad2(d.getUTCMonth() + 1) + '/' +
       d.getUTCFullYear();
}

function outerFunc(base) {
    var punc = "!";

    //inner function
    function returnString(ext) {
       return base + ext + punc;
    }

    return returnString;
}

Wie kann eine Funktion innerhalb einer anderen Funktion definiert werden? Können wir pad2 () von außerhalb meiner () Funktion aufrufen?

Bitte machen Sie etwas Licht darauf. Vielen Dank

Thomas
quelle
13
Funktionen können innerhalb von Funktionen erstellt werden. Das ist völlig richtig.
0x499602D2

Antworten:

140

Funktionen sind eine andere Art von Variablen in JavaScript (mit einigen Nuancen natürlich). Das Erstellen einer Funktion innerhalb einer anderen Funktion ändert den Funktionsumfang auf dieselbe Weise wie den Gültigkeitsbereich einer Variablen. Dies ist besonders wichtig für die Verwendung mit Schließungen, um die Gesamtverschmutzung durch globale Namespaces zu reduzieren.

Auf die in einer anderen Funktion definierten Funktionen kann außerhalb der Funktion nur zugegriffen werden, wenn sie an ein Objekt angehängt wurden, auf das außerhalb der Funktion zugegriffen werden kann:

function foo(doBar)
{
  function bar()
  {
    console.log( 'bar' );
  }

  function baz()
  {
    console.log( 'baz' );
  }

  window.baz = baz;
  if ( doBar ) bar();
}

In diesem Beispiel kann die baz-Funktion nach dem fooAusführen der Funktion verwendet werden, da sie überschrieben wird window.baz. Die Balkenfunktion ist für keinen anderen Kontext als die in der fooFunktion enthaltenen Bereiche verfügbar .

als anderes Beispiel:

function Fizz(qux)
{
  this.buzz = function(){
    console.log( qux );
  };
}

Die FizzFunktion ist als Konstruktor konzipiert, sodass sie beim Ausführen buzzdem neu erstellten Objekt eine Funktion zuweist .

zzzzBov
quelle
Was ist window.baz = baz? Warum ist diese Linie verfügbar?
Ziyang Zhang
@ZiyangZhang, der Absatz nach diesem Codeblock enthält die Erklärung, gab es einen bestimmten Teil, der unklar ist?
zzzzBov
35

Es heißt Schließung .

Grundsätzlich ist die in einer anderen Funktion definierte Funktion nur innerhalb dieser Funktion zugänglich. Kann aber als Ergebnis übergeben werden und dann kann dieses Ergebnis aufgerufen werden.

Es ist eine sehr mächtige Funktion. Weitere Erklärungen finden Sie hier:

javascript_closures_for_dummies.html Spiegel auf Archive.org

Tadeck
quelle
13
function x() {}

ist äquivalent (oder sehr ähnlich) zu

var x = function() {}

es sei denn, ich irre mich.

Es ist also nichts Komisches los.

Andreas
quelle
8
Die erste Syntax wird an den Anfang des Dokuments verschoben. Es ist also möglich, die Funktion 'x' aufzurufen, bevor die Funktion initialisiert wird.
Tom
10
Die erste Syntax wird Ihnen auch viel schönere Stack-Traces mit benannten Funktionen bringen, die zweite wird Ihnen Kopfschmerzen
bereiten
@TheZ Ich denke, Chrome hat kürzlich eine Inferenz zum Funktionsnamen zum Debuggen hinzugefügt, damit Sie im allgemeinen Fall nicht die gleichen Kopfschmerzen wie zuvor bekommen.
Jinglesthula
@jinglesthula Ja! Chrome hat diese
Namensinferenz vor einiger Zeit
10

Funktionsinstanziierung ist innerhalb und außerhalb von Funktionen zulässig. Innerhalb dieser Funktionen sind die verschachtelten Funktionen genau wie Variablen lokal und können daher nicht vom externen Bereich abgerufen werden.

function foo() {
    function bar() {
        return 1;
    }
    return bar();
}

foomanipuliert barin sich. barkann nicht vom äußeren Bereich berührt werden, es sei denn, es ist im äußeren Bereich definiert.

Das wird also nicht funktionieren:

function foo() {
    function bar() {
        return 1;
    }
}

bar(); // throws error: bar is not defined
0x499602D2
quelle
4

Wenn Sie eine Funktion innerhalb einer Funktion deklarieren, sind die inneren Funktionen nur in dem Bereich verfügbar, in dem sie deklariert sind, oder in Ihrem Fall pad2kann der nur im Bereich aufgerufen werden dmy.

Alle in vorhandenen Variablen dmysind in sichtbar pad2, aber es kommt nicht umgekehrt vor: D.

Pedrochaves
quelle
2

In Javascript (und vielen Sprachen) ist es völlig normal, Funktionen in Funktionen zu haben.

Nehmen Sie sich Zeit, um die Sprache zu lernen, und verwenden Sie sie nicht auf der Grundlage, dass sie dem ähnelt, was Sie bereits kennen. Ich würde vorschlagen, Douglas Crockfords Reihe von YUI-Präsentationen auf Javascript anzusehen, mit besonderem Schwerpunkt auf Akt III: Function the Ultimate (Link zum Herunterladen von Videos, Folien und Transkription)

Joaquim Rendeiro
quelle
0

function foo() {
  function bar() {
    return 1;
  }
}
bar();

Wird einen Fehler auslösen. Da barinnen definiert ist foo, barwird nur innen zugänglich sein foo.
Um es zu verwenden bar, müssen Sie es im Inneren ausführen foo.

function foo() {
  function bar() {
    return 1;
  }
  bar();
}

Justin Liu
quelle