7585 Stimmen

var Funktionsname = function() {} vs function Funktionsname() {}

Ich habe vor kurzem damit begonnen, den JavaScript-Code von jemand anderem zu pflegen. Ich behebe Fehler, füge Funktionen hinzu und versuche, den Code aufzuräumen und konsistenter zu machen.

Der vorherige Entwickler verwendete zwei Arten, Funktionen zu deklarieren, und ich kann nicht herausfinden, ob es einen Grund dafür gibt oder nicht.

Es gibt zwei Möglichkeiten:

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 jeweiligen Methode? Gibt es irgendetwas, das mit der einen Methode gemacht werden kann, was mit der anderen nicht möglich ist?

34voto

Kafka Punkte 462

In der Informatik spricht man von anonymen Funktionen und benannten Funktionen. Ich denke, der wichtigste Unterschied ist, dass eine anonyme Funktion nicht an einen Namen gebunden ist, daher der Name anonyme Funktion. In JavaScript ist sie ein Objekt erster Klasse, das zur Laufzeit dynamisch deklariert wird.

Für weitere Informationen über anonyme Funktionen und Lambda-Kalkül ist Wikipedia ein guter Ausgangspunkt: Anonyme Funktionen .

33voto

Rohan Punkte 12168

Gregs Antwort ist gut genug, aber ich möchte noch etwas hinzufügen, was ich gerade gelernt habe, als ich Douglas Crockfords Videos.

Funktionsausdruck:

var foo = function foo() {};

Funktionsanweisung:

function foo() {};

Die Funktionsanweisung ist nur eine Kurzform für var Anweisung mit einer function Wert.

Also

function foo() {};

erweitert sich auf

var foo = function foo() {};

Was sich weiter ausdehnt auf:

var foo = undefined;
foo = function foo() {};

Und sie werden beide an die Spitze des Codes gehievt.

Screenshot from video

32voto

Herc Punkte 507

Ich verwende den Variablen-Ansatz in meinem Code aus einem ganz bestimmten Grund, dessen Theorie oben in abstrakter Form behandelt wurde, aber ein Beispiel könnte einigen Leuten wie mir mit begrenzten JavaScript-Kenntnissen helfen.

Ich habe einen Code, den ich mit 160 unabhängig voneinander gestalteten Brandings ausführen muss. Der größte Teil des Codes befindet sich in gemeinsamen Dateien, aber markenspezifisches Material ist in einer separaten Datei, eine für jedes Branding.

Für einige Brandings sind bestimmte Funktionen erforderlich, für andere nicht. Manchmal muss ich neue Funktionen hinzufügen, um neue markenspezifische Dinge zu tun. Ich bin gerne bereit, den gemeinsamen Code zu ändern, aber ich möchte nicht alle 160 Sätze von Branding-Dateien ändern müssen.

Durch die Verwendung der Variablen-Syntax kann ich die Variable (ein Funktionszeiger im Wesentlichen) im freigegebenen Code deklarieren und entweder eine triviale Stub-Funktion zuweisen oder auf Null setzen.

Die ein oder zwei Brandings, die eine spezifische Implementierung der Funktion benötigen, können dann ihre Version der Funktion definieren und diese der Variablen zuweisen, wenn sie wollen, und der Rest tut nichts. Ich kann auf eine Null-Funktion testen, bevor ich sie im gemeinsamen Code ausführe.

Aus den obigen Kommentaren entnehme ich, dass es möglich sein könnte, auch eine statische Funktion neu zu definieren, aber ich denke, die variable Lösung ist schön und klar.

25voto

Joel Purra Punkte 22337

@EugeneLazutkin gibt ein Beispiel, in dem er benennt eine zugewiesene Funktion, um sie nutzen zu können shortcut() als interne Referenz auf sich selbst. John Resig gibt ein weiteres Beispiel - Kopieren einer rekursiven Funktion, die einem anderen Objekt zugeordnet ist in seinem Erlernen von fortgeschrittenem Javascript Lernprogramm. Obwohl die Zuweisung von Funktionen zu Eigenschaften hier nicht die eigentliche Frage ist, empfehle ich, das Tutorial aktiv auszuprobieren - führen Sie den Code aus, indem Sie auf die Schaltfläche in der oberen rechten Ecke klicken, und doppelklicken Sie auf den Code, um ihn nach Ihren Wünschen zu bearbeiten.

Beispiele aus dem Tutorium: rekursive Aufrufe in yell() :

Die Tests schlagen fehl, wenn das ursprüngliche Ninja-Objekt entfernt wird. (Seite 13)

var ninja = { 
  yell: function(n){ 
    return n > 0 ? ninja.yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." ); 

var samurai = { yell: ninja.yell }; 
var ninja = null; 

try { 
  samurai.yell(4); 
} catch(e){ 
  assert( false, "Uh, this isn't good! Where'd ninja.yell go?" ); 
}

Wenn Sie die Funktion, die rekursiv aufgerufen wird, benennen, werden die Tests bestanden. (Seite 14)

var ninja = { 
  yell: function yell(n){ 
    return n > 0 ? yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" ); 

var samurai = { yell: ninja.yell }; 
var ninja = {}; 
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." );

21voto

Ingo Kegel Punkte 44582

Ein weiterer Unterschied, der in den anderen Antworten nicht erwähnt wird, besteht darin, dass bei Verwendung der anonymen Funktion

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

und verwenden diese als Konstruktor wie in

var one = new functionOne();

では one.constructor.name wird nicht definiert. Function.name ist kein Standard, wird aber von Firefox, Chrome, anderen von Webkit abgeleiteten Browsern und IE 9+ unterstützt.

Con

function functionTwo() {
    // Some code
}
two = new functionTwo();

ist es möglich, den Namen des Konstruktors als String abzurufen mit two.constructor.name .

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