var funktionsname = funktion() {} vs funktion funktionsname() {}

Lesezeit: 8 Minuten

var funktionsname funktion vs funktion funktionsname
Richard Garside

Ich habe vor kurzem damit begonnen, den JavaScript-Code einer anderen Person zu warten. Ich behebe Fehler, füge Funktionen hinzu und versuche auch, den Code aufzuräumen und konsistenter zu machen.

Der vorherige Entwickler hat zwei Möglichkeiten zum Deklarieren von Funktionen verwendet, und ich kann nicht herausfinden, ob es einen Grund dafür gibt oder nicht.

Die zwei Wege sind:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

Was sind die Gründe für die Verwendung dieser beiden unterschiedlichen Methoden und was sind die Vor- und Nachteile der beiden? Gibt es irgendetwas, das mit einer Methode getan werden kann, was mit der anderen nicht möglich ist?

var funktionsname funktion vs funktion funktionsname
Eugen Lazutkin

Zuerst möchte ich Greg korrigieren: function abc(){} ist ebenfalls im Geltungsbereich – der Name abc wird in dem Geltungsbereich definiert, in dem diese Definition angetroffen wird. Beispiel:

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

Zweitens ist es möglich, beide Stile zu kombinieren:

var xyz = function abc(){};

xyz wird wie gewohnt definiert, abc ist in allen Browsern außer Internet Explorer undefiniert – verlassen Sie sich nicht darauf, dass es definiert ist. Aber es wird in seinem Körper definiert:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

Wenn Sie Alias-Funktionen auf allen Browsern verwenden möchten, verwenden Sie diese Art der Erklärung:

function abc(){};
var xyz = abc;

In diesem Fall beides xyz und abc sind Aliase desselben Objekts:

console.log(xyz === abc); // prints "true"

Ein zwingender Grund für die Verwendung des kombinierten Stils ist das “Name”-Attribut von Funktionsobjekten (vom Internet Explorer nicht unterstützt). Grundsätzlich, wenn Sie eine Funktion wie definieren

function abc(){};
console.log(abc.name); // prints "abc"

sein Name wird automatisch zugewiesen. Aber wenn Sie es wie definieren

var abc = function(){};
console.log(abc.name); // prints ""

sein Name ist leer – wir haben eine anonyme Funktion erstellt und sie einer Variablen zugewiesen.

Ein weiterer guter Grund, den kombinierten Stil zu verwenden, besteht darin, einen kurzen internen Namen zu verwenden, um auf sich selbst zu verweisen, während ein langer, nicht widersprüchlicher Name für externe Benutzer bereitgestellt wird:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

Im obigen Beispiel können wir dasselbe mit einem externen Namen machen, aber es wird zu unhandlich (und langsamer).

(Eine andere Möglichkeit, auf sich selbst zu verweisen, ist die Verwendung arguments.calleeder immer noch relativ lang ist und im strikten Modus nicht unterstützt wird.)

Tief im Inneren behandelt JavaScript beide Anweisungen unterschiedlich. Dies ist eine Funktionsdeklaration:

function abc(){}

abc Hier ist überall im aktuellen Geltungsbereich definiert:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

Außerdem hob es durch a return Aussage:

// We can call it here
abc(); // Works
return;
function abc(){}

Dies ist ein Funktionsausdruck:

var xyz = function(){};

xyz hier wird ab dem Zuordnungspunkt definiert:

// We can't call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

Funktionsdeklaration vs. Funktionsausdruck ist der wahre Grund, warum es einen Unterschied gibt, den Greg demonstriert.

Lustige Tatsache:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

Ich persönlich bevorzuge die Deklaration “Funktionsausdruck”, da ich so die Sichtbarkeit steuern kann. Wenn ich die Funktion wie definiere

var abc = function(){};

Ich weiß, dass ich die Funktion lokal definiert habe. Wenn ich die Funktion wie definiere

abc = function(){};

Ich weiß, dass ich es global definiert habe, vorausgesetzt, ich habe es nicht definiert abc irgendwo in der Kette von Zielfernrohren. Dieser Definitionsstil ist auch im Innenbereich belastbar eval(). Während die Definition

function abc(){};

hängt vom Kontext ab und lässt Sie möglicherweise raten, wo es tatsächlich definiert ist, insbesondere im Fall von eval() — Die Antwort lautet: Es kommt auf den Browser an.

  • var abc = Funktion () {}; console.log (abc.name); // “abc” // ab 2021

    – lfx_cool

    3. April 2021 um 16:27 Uhr


  • Anscheinend wurde die JS-Laufzeit intelligenter. Fassen Sie es aber zusammen und: var abc = (() => function(){})(); console.log (abc.name); // nichts

    – Eugen Lazutkin

    15. April 2021 um 1:17 Uhr


  • @EugeneLazutkin Sie führen die Funktion aus und versuchen, den Namen des Ergebnisses zu lesen. Entferne das ‘();’ Teil und dein Beispiel wird richtig sein 😉

    – ikirachen

    7. Oktober 2021 um 16:51 Uhr

  • @ikirachen Ich verstehe nicht, worauf Sie sich beziehen. Könnten Sie Ihren Vorschlag mit einem kleinen Kontext versehen, damit ich herausfinden kann, wovon Sie sprechen?

    – Eugen Lazutkin

    11. Oktober 2021 um 14:52 Uhr

  • @EugeneLazutkin Sie definieren eine Funktion und rufen sie sofort auf (rufen sie auf), auch als IIFE (Immediately Invoked Function Expression) bezeichnet. Dies ist eine Methode zur Implementierung des lexikalischen Bereichs (nichts aus dem IIFE ist außerhalb davon zugänglich). Also der Wert von abc ist nicht die Funktion selbst, sondern der Rückgabewert dieser Funktion. Es ist sinnvoll, dass abc.name leer ist, da abc eine unbenannte Funktion zurückgibt. @ikirachen erwähnte das Entfernen der () denn das ist es, was die Funktion aufruft. Ohne das wird es nur in überflüssige Klammern gepackt.

    – Sinjai

    16. November 2021 um 23:43 Uhr

1646891117 186 var funktionsname funktion vs funktion funktionsname
Christian C. Salvado

Apropos globaler Kontext, sowohl die var Aussage und a FunctionDeclaration Am Ende wird ein erstellt nicht löschbar -Eigenschaft auf dem globalen Objekt, sondern den Wert von beiden überschrieben werden können.

Der subtile Unterschied zwischen den beiden Möglichkeiten besteht darin, dass, wenn die Variable Instanziierung Der Prozess führt (vor der eigentlichen Codeausführung) alle mit deklarierten Bezeichner aus var wird mit initialisiert undefinedund diejenigen, die von verwendet werden FunctionDeclaration‘s werden ab diesem Moment verfügbar sein, zum Beispiel:

 alert(typeof foo); // 'function', it's already available
 alert(typeof bar); // 'undefined'
 function foo () {}
 var bar = function () {};
 alert(typeof bar); // 'function'

Die Beauftragung der bar FunctionExpression erfolgt bis zur Laufzeit.

Eine globale Eigenschaft, die von a erstellt wurde FunctionDeclaration kann wie ein Variablenwert problemlos überschrieben werden, zB:

 function test () {}
 test = null;

Ein weiterer offensichtlicher Unterschied zwischen Ihren beiden Beispielen besteht darin, dass die erste Funktion keinen Namen hat, die zweite jedoch, was beim Debuggen (dh beim Untersuchen eines Aufrufstapels) sehr nützlich sein kann.

Über Ihr bearbeitetes erstes Beispiel (foo = function() { alert('hello!'); };), es handelt sich um eine nicht deklarierte Zuweisung, empfehle ich Ihnen dringend, immer die zu verwenden var Stichwort.

Mit einer Aufgabe, ohne die var -Anweisung, wenn der referenzierte Bezeichner nicht in der Bereichskette gefunden wird, wird er zu einem löschbar Eigenschaft des globalen Objekts.

Auch nicht deklarierte Zuweisungen werfen ein ReferenceError auf ECMAScript 5 unter strikter Modus.

Muss man lesen:

Notiz: Diese Antwort wurde aus einer anderen Frage zusammengeführt, in der der größte Zweifel und das Missverständnis des OP darin bestand, dass mit a deklarierte Identifikatoren FunctionDeclarationkonnte nicht überschrieben werden, was nicht der Fall ist.

1646891118 844 var funktionsname funktion vs funktion funktionsname
Peter Mortensen

Die beiden Codeausschnitte, die Sie dort gepostet haben, verhalten sich für fast alle Zwecke gleich.

Der Unterschied im Verhalten besteht jedoch darin, dass bei der ersten Variante (var functionOne = function() {}), kann diese Funktion erst nach diesem Punkt im Code aufgerufen werden.

Bei der zweiten Variante (function functionTwo()) ist die Funktion für Code verfügbar, der oberhalb der Deklaration der Funktion ausgeführt wird.

Denn bei der ersten Variante wird die Funktion der Variablen zugewiesen foo zur Laufzeit. Im zweiten wird die Funktion diesem Bezeichner zugewiesen, foozur Analysezeit.

Weitere technische Informationen

JavaScript hat drei Möglichkeiten, Funktionen zu definieren.

  1. Ihr erster Ausschnitt zeigt a Funktionsausdruck. Dazu gehört die Verwendung der “Funktion”-Operator um eine Funktion zu erstellen – das Ergebnis dieses Operators kann in jeder Variablen- oder Objekteigenschaft gespeichert werden. Der Funktionsausdruck ist auf diese Weise mächtig. Der Funktionsausdruck wird oft als “anonyme Funktion” bezeichnet, da er keinen Namen haben muss,
  2. Ihr zweites Beispiel ist a Funktionsdeklaration. Dies nutzt die Aussage “Funktion”. um eine Funktion zu erstellen. Die Funktion wird zur Analysezeit verfügbar gemacht und kann überall in diesem Bereich aufgerufen werden. Sie können es später immer noch in einer Variablen- oder Objekteigenschaft speichern.
  3. Die dritte Art, eine Funktion zu definieren, ist die „Function()“-Konstruktor, die in Ihrem ursprünglichen Beitrag nicht angezeigt wird. Es wird nicht empfohlen, dies zu verwenden, da es genauso funktioniert wie eval()was seine Probleme hat.

1646891118 163 var funktionsname funktion vs funktion funktionsname
Gemeinschaft

Eine bessere Erklärung für Gregs Antwort

functionTwo();
function functionTwo() {
}

Warum kein Fehler? Uns wurde immer beigebracht, dass Ausdrücke von oben nach unten ausgeführt werden (??)

Weil:

Funktionsdeklarationen und Variablendeklarationen werden immer verschoben (hoisted) vom JavaScript-Interpreter unsichtbar an den Anfang ihres enthaltenden Gültigkeitsbereichs gesetzt. Funktionsparameter und sprachdefinierte Namen sind offensichtlich bereits vorhanden. Ben Kirsche

Dies bedeutet, dass Code wie folgt:

functionOne();                  ---------------      var functionOne;
                                | is actually |      functionOne();
var functionOne = function(){   | interpreted |-->
};                              |    like     |      functionOne = function(){
                                ---------------      };

Beachten Sie, dass der Zuordnungsteil der Deklarationen nicht gehisst wurde. Nur der Name wird gehisst.

Aber im Fall von Funktionsdeklarationen wird auch der gesamte Funktionsrumpf gehisst:

functionTwo();              ---------------      function functionTwo() {
                            | is actually |      };
function functionTwo() {    | interpreted |-->
}                           |    like     |      functionTwo();
                            ---------------

986460cookie-checkvar funktionsname = funktion() {} vs funktion funktionsname() {}

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy