Warum quält diese Frage selbst erfahrene Entwickler?
\nWenn Sie jemals in JavaScript geschrieben haben, sind Sie bestimmt beiden Arten der Funktionsdeklaration begegnet. Sie sehen ähnlich aus, verhalten sich aber völlig unterschiedlich. Auf Stack Overflow hat diese Frage tausende Aufrufe und Dutzende Diskussionsseiten gesammelt. Warum? Weil das Unverständnis des Unterschieds zwischen var functionName = function() {} und function functionName() {} zu Bugs führt, die schwer zu finden sind.
Heute klären wir dieses Thema ein für alle Mal. Sie erfahren, was function declaration und function expression sind, wie hoisting funktioniert und wann welche Methode verwendet werden sollte. Los geht's!
\n\nWas verbirgt sich hinter der Syntax?
\nBeginnen wir mit den Grundlagen. Die erste Variante ist die Function Declaration (Funktionsdeklaration):
\nfunction greet() {\n console.log('Hallo!');\n}\nDie zweite ist die Function Expression (Funktionsausdruck):
\nconst greet = function() {\n console.log('Hallo!');\n};\nBeachten Sie: Im ersten Fall hat die Funktion einen Namen und steht am Anfang der Zeile. Im zweiten Fall weisen wir eine anonyme Funktion der Variablen greet zu. Aber das Interessanteste beginnt, wenn wir betrachten, wie JavaScript diese Deklarationen verarbeitet.
Der Hauptunterschied: Hoisting
\nHoisting ist ein Mechanismus in JavaScript, bei dem Deklarationen von Variablen und Funktionen vor der Codeausführung an den Anfang ihres Gültigkeitsbereichs verschoben werden. Er funktioniert jedoch unterschiedlich für declaration und expression.
\n\nFunction Declaration wird vollständig gehoben
\nWenn Sie function functionName() {} verwenden, „hebt“ JavaScript die gesamte Funktionsdeklaration nach oben. Das bedeutet, Sie können die Funktion aufrufen, bevor sie im Code deklariert ist:
sayHello(); // "Hallo!"\n\nfunction sayHello() {\n console.log('Hallo!');\n}\nDer Code wird fehlerfrei ausgeführt. Das ist praktisch, kann aber Anfänger verwirren.
\n\nFunction Expression wird nicht gehoben
\nBei var functionName = function() {} ist die Geschichte anders. Nur die Variablendeklaration wird gehoben, nicht ihr Wert. Die Funktion bleibt an Ort und Stelle:
sayHello(); // TypeError: sayHello is not a function\n\nvar sayHello = function() {\n console.log('Hallo!');\n};\nWarum ist das so? Weil var die Deklaration der Variablen sayHello (mit dem Wert undefined) hebt, die Zuweisung der Funktion erfolgt erst in der Zeile mit dem Ausdruck. Daher ist sayHello bis zu dieser Zeile undefined, und der Versuch, es als Funktion aufzurufen, führt zu einem Fehler.
Übrigens: Wenn Sie var durch let oder const ersetzen, wird der Fehler ein anderer sein – ReferenceError: Cannot access 'sayHello' before initialization. Dies liegt daran, dass let und const erst zum Zeitpunkt der Deklaration initialisiert werden (die sogenannte „temporäre Totzone“).
Gültigkeitsbereich: Ein weiterer Stolperstein
\nSowohl function declaration als auch function expression unterliegen den Regeln des Gültigkeitsbereichs. Es gibt jedoch eine Nuance.
\n\nFunction Declaration ist innerhalb des Blocks sichtbar
\nObwohl die function declaration gehoben wird, ist ihr Gültigkeitsbereich auf den Block beschränkt (im strikten Modus):
\n'use strict';\nif (true) {\n function greet() {\n console.log('Innerhalb des Blocks');\n }\n greet(); // "Innerhalb des Blocks"\n}\ngreet(); // ReferenceError: greet is not defined (im strikten Modus)\nIm nicht-strikten Modus „schlüpft“ eine solche Deklaration nach außen, aber darauf sollte man sich nicht verlassen.
\n\nFunction Expression lebt in ihrer Variablen
\nBei der function expression ist alles vorhersehbar: Die Funktion ist nur dort verfügbar, wo die Variable verfügbar ist. Wenn verschiebe