Funktionsdeklaration als var statt function

28

Ich sehe immer mehr, wie Funktionen deklariert werden

var foo = function() {

    // things
};

Statt wie ich es gelernt hatte

function foo() {

    // things
}

Was ist der Unterschied? Bessere Leistung? Umfang? Sollte ich diese Methode anwenden?

Steve Robbins
quelle
es ist erwähnenswert, dass in javascript funktionen erstklassige bürger sind . Auf diese Weise können Sie Verhalten wie Objekte weitergeben. Dies ist unter anderem für Rückrufe und Delegierungen sehr nützlich.
Chris Bye
Umfang . Der Umbruch von Variablennamen "// things" verhindert im Wesentlichen / hoffentlich Namenskollisionen der "// things", die er umbricht, einschließlich anderer JavaScript-Dateien. Eine andere Möglichkeit ist, dass Sie einen Namespace "foo" erstellt haben.
Radarbob

Antworten:

25

var foo = function() {} definiert eine Variable, die auf eine anonyme Funktion verweist.

function foo() {}definiert eine benannte Funktion foo.

Entweder kann der Name als Funktionsparameter übergeben werden, oder es kann eine Instanz erstellt werden, wenn die beabsichtigte Verwendung für OOP ist.

Am Ende des Tages wird der von Ihnen verwendete weitgehend von Ihrem speziellen Anwendungsfall bestimmt (so macht Javascript Spaß;)). Wenn Sie die erstere verwenden, empfehle ich dringend , die Funktion zu benennen:

var foo = function MY_function() {}. Diese Namenskonvention hilft, dass Ihr Debugger-Callstack nicht unbrauchbar wird.

Demian Brecht
quelle
1
Habe dort einen Fehler bei function () MY ...
Erik Reppen
1
@Demian Brecht, und wie sieht es mit var foo = function foo () {...} aus?
Shabunc
@shabunc: Was ist damit? Es ist im letzten Absatz meiner Antwort aufgeführt.
Demian Brecht
@Demian Brecht, nein, eigentlich heißt die Variable im letzten Absatz foound die Funktion heißtMY_function
shabunc
@shabunc: Der Name spielt keine Rolle. Entscheidend ist der Wert im Callstack. Als Beispiel ist [NAMESPACE] _ [fn name] die von Mozilla verwendete Konvention. Der Name selbst spielt keine Rolle, solange Ihre Konvention im gesamten Projekt konsistent ist.
Demian Brecht
13

Funktionsausdruck:

//someFunction(); //wouldn't work when uncommented
var someFunction = function(){ alert('yay'); };

Der Funktionsausdruck ist in diesem Fall anonym, wird aber zu Referenzzwecken einer Variablen zugewiesen. Dies unterscheidet sich von einer beschrifteten Funktionsanweisung auf folgende Weise:

  • es kann nicht gehisst werden (wird aufgerufen, bevor es definiert ist)
  • new someFunction().constructor.name === 'someFunction';//false Instanzen erhalten den Variablennamen für constructor.name nicht, da dem Variablennamen ein Verweis auf die Funktion zugewiesen ist, aber der Variablenname und nicht die Funktion mit dem Variablennamen verknüpft ist

In einer beschrifteten Funktionsanweisung:

//someFunction(); //works when uncommented
function someFunction(){ alert('yay'); }
  • Hebearbeiten
  • new someFunction().constructor.name === 'someFunction'; //true Der Name ist direkt an die Funktion gebunden.

Im Allgemeinen gibt es keinen wirklich guten Grund, var einen Ausdruck zu geben, es sei denn, Sie möchten, dass Aufrufe fehlschlagen, wenn Dinge verschoben werden oder Sie eine Methode in einer Zeile definieren / zuweisen. Ich finde das Heben im Grunde nützlich, um Objekte mit internen Funktions- und Methodendefinitionen zu organisieren, damit ich das tatsächliche Verhalten des Objekts nachvollziehen und einzeilige öffentliche Methodendefinitionen durchführen kann (indem ich nur Funktionen this.mit demselben Namen zuordne ) Ort für die einfache Bezugnahme. Sie sollten immer versuchen, beschriftete Anweisungen für Konstruktoren (IMO) zu verwenden, damit Sie den 'Typ' eines Objekts über seinen Konstruktor identifizieren können.

Erik Reppen
quelle
8

Ihr erstes Beispiel ist ein Ausdruck, während das zweite Beispiel a ist Anweisung ist . Das Definieren von Funktionen als Ausdrücke ermöglicht eine größere Flexibilität, wenn die Definition auftreten kann, was Sie ihr zuweisen können, dass Sie sie als Parameter übergeben können usw.

Beispielsweise:

SomeThing('abc', function(a,b) {return a*b;});

vs ...

function tmp(a,b) { 
    return a*b;
}

SomeThing('abc', tmp);

Komplexere Beispiele würden ohne die Syntax des Funktionsausdrucks zu kompliziert.

Schauen Sie unter https://stackoverflow.com/questions/111102/how-do-javascript-closures-work nach

gahooa
quelle
4

Der praktische Hauptunterschied ist das Heben. Beispielsweise:

foo(); // alerts 'hello'
function foo() {alert('hello');}

vs

foo(); // throws an error since foo is undefined
var foo = function() {alert('hello');}

Auch dies ist undefiniertes Verhalten

function foo(){
  if (true) {
    function bar(){}
  }
  bar();
}

während das ok ist.

function foo(){
  if (true) {
    var bar = function(){}
  }
  bar();
}
Austin
quelle
7
Es ist absolut nichts Falsches daran, eine Funktion in einer Funktion in JS zu definieren. Es gibt nicht viele Stellen, an denen Sie in JS keine Funktion definieren können.
Erik Reppen
2
@ErikReppen Sie können definitiv keine Funktionsdeklarationen in Nicht-Funktionsblöcken verwenden (wie in einer if-Anweisung). Ich kann nicht finden, wo ich gelesen habe, dass sie nicht in einer anderen Funktion verwendet werden können.
Austin
@Austin Auch an einer Funktionsdefinition in einer ifAnweisung ist nichts auszusetzen !
Tim
@Austin: Vielleicht hast du es an w3schools gelesen? ;)
Demian Brecht
2
@ErikReppen Funktionsausdrücke können überall verwendet werden. Funktionsdeklarationen können nicht sein. Siehe stackoverflow.com/questions/10069204/…
Austin