web-dev-qa-db-ger.com

var functionName = Funktion () {} vs Funktion Funktionsname () {}

Ich habe vor kurzem damit begonnen, den JavaScript-Code eines anderen Benutzers zu verwalten. Ich korrigiere Fehler, füge Funktionen hinzu und versuche, den Code aufzuräumen und ihn einheitlicher zu gestalten.

Der bisherige Entwickler verwendet zwei Möglichkeiten, Funktionen zu deklarieren, und ich kann nicht herausfinden, ob es einen Grund gibt oder nicht.

Die zwei Möglichkeiten sind:

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

Was sind die Gründe für die Verwendung dieser zwei verschiedenen Methoden und welche Vor- und Nachteile haben beide? Gibt es etwas, das mit einer Methode möglich ist, mit der anderen Methode nicht?

6315
Richard Garside

Der Unterschied ist, dass functionOne ein Funktionsausdruck ist und daher nur definiert wird, wenn diese Zeile erreicht ist, wohingegen functionTwo eine Funktionsdeklaration ist und definiert wird, sobald die umgebende Funktion oder das Skript ausgeführt wird (aufgrund von hoisting ). 

Zum Beispiel einen Funktionsausdruck:

// TypeError: functionOne is not a function
functionOne();

var functionOne = function() {
  console.log("Hello!");
};

Und eine Funktionsdeklaration: 

// Outputs: "Hello!"
functionTwo();

function functionTwo() {
  console.log("Hello!");
}

Das bedeutet auch, dass Sie Funktionen nicht mit Funktionsdeklarationen bedingt definieren können:

if (test) {
   // Error or misbehavior
   function functionThree() { doSomething(); }
}

Das Obige definiert functionThree unabhängig von tests Wert - es sei denn, use strict ist wirksam. In diesem Fall wird einfach ein Fehler ausgegeben.

4694
Greg

Zuerst möchte ich Greg korrigieren: function abc(){} ist auch ein Bereich - der Name abc ist in dem Bereich definiert, in dem diese Definition gefunden 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 üblich definiert, abc ist in allen Browsern undefiniert, aber Internet Explorer - verlassen Sie sich nicht auf die Definition. 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 Funktionen in allen Browsern als Aliasnamen verwenden möchten, verwenden Sie diese Art der Deklaration:

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

In diesem Fall sind sowohl xyz als auch abc Aliase desselben Objekts:

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

Ein zwingender Grund für die Verwendung des kombinierten Stils ist das Attribut "name" von Funktionsobjekten ( nicht von Internet Explorer unterstützt). Grundsätzlich bei der Definition einer Funktion wie

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

sein Name wird automatisch vergeben. Aber wenn du es gerne definierst

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

der Name ist leer. Wir haben eine anonyme Funktion erstellt und einer Variablen zugewiesen.

Ein weiterer guter Grund für die Verwendung des kombinierten Stils ist die Verwendung eines kurzen internen Namens, um auf sich selbst zu verweisen, während für externe Benutzer ein langer, nicht in Konflikt stehender Name angegeben 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 tun, aber es ist zu unhandlich (und langsamer).

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

Im Grunde behandelt JavaScript beide Anweisungen unterschiedlich. Dies ist eine Funktionsdeklaration:

function abc(){}

abc ist hier überall im aktuellen Gültigkeitsbereich definiert:

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

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

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

Es wurde auch durch eine return-Anweisung gehisst:

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

Dies ist ein Funktionsausdruck:

var xyz = function(){};

xyz ist hier vom Zuordnungspunkt aus 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 Greg einen Unterschied zeigt.

Spaß Fakt:

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

Ich persönlich bevorzuge die Deklaration "Funktionsausdruck", da ich auf diese Weise die Sichtbarkeit steuern kann. Wenn ich die Funktion gerne definiere

var abc = function(){};

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

abc = function(){};

Ich weiß, dass ich es global definiert habe, vorausgesetzt, ich habe abc nirgendwo in der Kette von Gültigkeitsbereichen definiert. Dieser Definitionsstil ist auch bei Verwendung in eval() belastbar. Während der Definition

function abc(){};

hängt vom Kontext ab und lässt Sie vermuten, wo genau er definiert ist, insbesondere im Fall von eval() - die Antwort lautet: Sie hängt vom Browser ab.

1853
Eugene Lazutkin

Hier ist der Überblick über die Standardformulare, die Funktionen erstellen: (Ursprünglich für eine andere Frage geschrieben, aber angepasst, nachdem sie in die kanonische Frage verschoben wurde.)

Bedingungen:

Die Schnellliste:

  • Funktionserklärung

  • "Anonym" function Ausdruck (der trotz des Begriffs manchmal Funktionen mit Namen erstellt)

  • Benannter function Ausdruck

  • Accessor Function Initializer (ES5 +)

  • Pfeilfunktionsausdruck (ES2015 +) (der wie anonyme Funktionsausdrücke keinen expliziten Namen enthält und dennoch Funktionen mit Namen erstellen kann)

  • Methodendeklaration im Object Initializer (ES2015 +)

  • Konstruktor- und Methodendeklarationen in class (ES2015 +)

Funktionserklärung

Die erste Form ist eine Funktionsdeklaration, die so aussieht:

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

Eine Funktionsdeklaration ist eine Deklaration; Es ist keine Aussage oder ein Ausdruck. Als solches folgen Sie ihm nicht mit einem ; (obwohl dies harmlos ist).

Eine Funktionsdeklaration wird verarbeitet, wenn die Ausführung in den Kontext eintritt, in dem sie angezeigt wird , bevor ein schrittweiser Code ausgeführt wird. Die erstellte Funktion erhält einen korrekten Namen (x im obigen Beispiel), und dieser Name wird in den Bereich eingefügt, in dem die Deklaration angezeigt wird.

Da es vor jedem schrittweisen Code im selben Kontext verarbeitet wird, können Sie Folgendes tun:

x(); // Works even though it's above the declaration
function x() {
    console.log('x');
}

Bis ES2015 enthielt die Spezifikation keine Beschreibung der Funktionsweise einer JavaScript-Engine, wenn Sie eine Funktionsdeklaration in eine Kontrollstruktur wie try, if, switch, while einfügen. usw., wie folgt:

if (someCondition) {
    function foo() {    // <===== HERE THERE
    }                   // <===== BE DRAGONS
}

Und da sie verarbeitet werden bevor Schritt für Schritt Code ausgeführt wird, ist es schwierig zu wissen, was zu tun ist, wenn sie sich in einer Kontrollstruktur befinden.

Obwohl dies bis ES2015 nicht angegeben war, war es eine zulässige Erweiterung, um Funktionsdeklarationen in Blöcken zu unterstützen. Leider (und unvermeidlich) haben verschiedene Motoren verschiedene Dinge getan.

Ab ES2015 steht in der Spezifikation, was zu tun ist. In der Tat gibt es drei verschiedene Dinge zu tun:

  1. Wenn Sie sich in einem Webbrowser im Loose-Modus nicht ​​befinden, sollte die JavaScript-Engine eines tun
  2. Wenn Sie sich in einem Webbrowser im Loose-Modus befinden, sollte die JavaScript-Engine etwas anderes tun
  3. Im strict ​​-Modus (Browser oder nicht) soll die JavaScript-Engine noch etwas anderes tun

Die Regeln für die Loose-Modi sind knifflig, aber im strict ​​-Modus sind Funktionsdeklarationen in Blöcken einfach: Sie sind für den Block lokal (sie haben block scope, das heißt auch neu in ES2015), und sie werden an die Spitze des Blocks gehievt. So:

"use strict";
if (someCondition) {
    foo();               // Works just fine
    function foo() {
    }
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
                         // because it's not in the same block)

"Anonym" function Ausdruck

Die zweite gebräuchliche Form heißt anonymer Funktionsausdruck:

var y = function () {
    console.log('y');
};

Wie alle Ausdrücke wird es ausgewertet, wenn es bei der schrittweisen Ausführung des Codes erreicht ist.

In ES5 hat die erstellte Funktion keinen Namen (sie ist anonym). In ES2015 wird der Funktion nach Möglichkeit ein Name zugewiesen, indem auf den Kontext geschlossen wird. Im obigen Beispiel wäre der Name y. Ähnliches geschieht, wenn die Funktion der Wert eines Eigenschaftsinitialisierers ist. (Einzelheiten dazu, wann dies geschieht, und zu den Regeln, suchen Sie nach SetFunctionName in der Spezifikation - es erscheint überall am Ort.)

Benannter function Ausdruck

Die dritte Form ist ein benannter Funktionsausdruck ("NFE"):

var z = function w() {
    console.log('zw')
};

Die erstellte Funktion hat einen eigenen Namen (w in diesem Fall). Wie alle Ausdrücke wird dies ausgewertet, wenn es in der schrittweisen Ausführung des Codes erreicht ist. Der Name der Funktion wird nicht ​​zum Gültigkeitsbereich des Ausdrucks hinzugefügt. Der Name ist ​​im Gültigkeitsbereich der Funktion selbst:

var z = function w() {
    console.log(typeof w); // "function"
};
console.log(typeof w);     // "undefined"

Beachten Sie, dass NFEs häufig zu Fehlern bei der Implementierung von JavaScript geführt haben. IE8 und frühere Versionen behandeln beispielsweise NFEs völlig falsch , wodurch zwei verschiedene Funktionen zu zwei verschiedenen Zeiten erstellt werden. Frühere Versionen von Safari hatten ebenfalls Probleme. Die gute Nachricht ist, dass die aktuellen Browserversionen (IE9 und höher, aktuelle Safari) diese Probleme nicht mehr haben. (Leider ist IE8 zum jetzigen Zeitpunkt weiterhin weit verbreitet, sodass die Verwendung von NFEs mit Code für das Web im Allgemeinen immer noch problematisch ist.)

Accessor Function Initializer (ES5 +)

Manchmal können sich Funktionen weitgehend unbemerkt einschleichen. das ist der Fall mit Accessor-Funktionen. Hier ist ein Beispiel:

var obj = {
    value: 0,
    get f() {
        return this.value;
    },
    set f(v) {
        this.value = v;
    }
};
console.log(obj.f);         // 0
console.log(typeof obj.f);  // "number"

Beachten Sie, dass ich bei Verwendung der Funktion () nicht verwendet habe! Das liegt daran, dass es sich um eine Accessor-Funktion für eine Eigenschaft handelt. Wir bekommen und setzen die Eigenschaft auf normale Weise, aber hinter den Kulissen wird die Funktion aufgerufen.

Sie können Accessor-Funktionen auch mit Object.defineProperty, Object.defineProperties und dem weniger bekannten zweiten Argument zu Object.create erstellen.

Pfeilfunktionsausdruck (ES2015 +)

ES2015 bringt uns die Pfeilfunktion. Hier ist ein Beispiel:

var a = [1, 2, 3];
var b = a.map(n => n * 2);
console.log(b.join(", ")); // 2, 4, 6

Sehen Sie, dass n => n * 2 sich im map() -Aufruf versteckt? Das ist eine Funktion.

Ein paar Dinge über Pfeilfunktionen:

  1. Sie haben kein eigenes this. Stattdessen close over das this des Kontexts, in dem sie definiert sind. (Sie schließen auch über arguments und gegebenenfalls super.) Dies bedeutet, dass das this in ihnen dasselbe ist wie das this, in dem sie erstellt wurden, und kann nicht geändert werden.

  2. Wie Sie bereits bemerkt haben, verwenden Sie das Schlüsselwort function nicht. Stattdessen verwenden Sie =>.

Das obige Beispiel n => n * 2 ist eine davon. Wenn Sie mehrere Argumente haben, um die Funktion zu übergeben, verwenden Sie parens:

var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6

(Denken Sie daran, dass Array#map den Eintrag als erstes Argument und den Index als zweites übergibt.)

In beiden Fällen ist der Körper der Funktion nur ein Ausdruck; Der Rückgabewert der Funktion ist automatisch das Ergebnis dieses Ausdrucks (Sie verwenden kein explizites return).

Wenn Sie mehr als nur einen einzelnen Ausdruck ausführen, verwenden Sie wie gewohnt {} und ein explizites return (wenn Sie einen Wert zurückgeben müssen):

var a = [
  {first: "Joe", last: "Bloggs"},
  {first: "Albert", last: "Bloggs"},
  {first: "Mary", last: "Albright"}
];
a = a.sort((a, b) => {
  var rv = a.last.localeCompare(b.last);
  if (rv === 0) {
    rv = a.first.localeCompare(b.first);
  }
  return rv;
});
console.log(JSON.stringify(a));

Die Version ohne { ... } heißt eine Pfeilfunktion mit einem expression body oder concise body. (Auch: A prägnante Pfeilfunktion.) Diejenige, bei der { ... } den Körper definiert, ist eine Pfeilfunktion mit einem Funktionskörper. (Auch: A verbose Pfeilfunktion.)

Methodendeklaration im Object Initializer (ES2015 +)

ES2015 ermöglicht eine kürzere Form der Deklaration einer Eigenschaft, die auf eine Funktion namens Methodendefinition verweist. es sieht aus wie das:

var o = {
    foo() {
    }
};

das fast Äquivalent in ES5 und früher wäre:

var o = {
    foo: function foo() {
    }
};

der Unterschied (abgesehen von der Ausführlichkeit) besteht darin, dass eine Methode super verwenden kann, eine Funktion jedoch nicht. Wenn Sie zum Beispiel ein Objekt hätten, das valueOf mithilfe der Methodensyntax definiert (say), könnte es super.valueOf() verwenden, um den Wert Object.prototype.valueOf abzurufen (bevor Sie vermutlich etwas anderes mit tun würden) it), während die ES5-Version stattdessen Object.prototype.valueOf.call(this) ausführen müsste.

Das bedeutet auch, dass die Methode einen Verweis auf das Objekt hat, für das sie definiert wurde. Wenn das Objekt also temporär ist (z. B. übergeben Sie es als eines der Quellobjekte an Object.assign), Methodensyntax - could bedeutet, dass das Objekt im Speicher verbleibt, wenn es ansonsten möglicherweise überflüssig geworden wäre (wenn die JavaScript-Engine diese Situation nicht erkennt und wenn keine der Methoden super verwendet).

Konstruktor- und Methodendeklarationen in class (ES2015 +)

ES2015 enthält die Syntax class, einschließlich deklarierter Konstruktoren und Methoden:

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    getFullName() {
        return this.firstName + " " + this.lastName;
    }
}

Es gibt oben zwei Funktionsdeklarationen: Eine für den Konstruktor, der den Namen Person erhält, und eine für getFullName, eine Funktion, die Person.prototype zugewiesen ist.

599
T.J. Crowder

Wenn Sie über den globalen Kontext sprechen, erstellen sowohl die var-Anweisung als auch eine FunctionDeclaration am Ende eine nicht löschbare -Eigenschaft für das globale Objekt. Der Wert von kann jedoch überschrieben werden.

Der subtile Unterschied zwischen den beiden Methoden besteht darin, dass bei Ausführung des Prozesses Variable Instantiation (vor der eigentlichen Codeausführung) alle mit var deklarierten Bezeichner mit undefined initialisiert werden und die von den FunctionDeclaration-Werten verwendeten seit diesem Moment verfügbar sind , zum Beispiel:

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

Die Zuweisung der barFunctionExpression erfolgt bis zur Laufzeit.

Eine globale Eigenschaft, die von einer FunctionDeclaration erstellt wird, kann wie ein Variablenwert problemlos überschrieben werden, z.

 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 (d. H. Prüfen eines Aufrufstapels) sehr nützlich sein kann.

Was Ihr bearbeitetes erstes Beispiel (foo = function() { alert('hello!'); };) betrifft, handelt es sich um eine nicht deklarierte Zuweisung. Ich würde Ihnen dringend empfehlen, immer das Schlüsselwort var zu verwenden.

Wenn bei einer Zuweisung ohne die Anweisung var der referenzierte Bezeichner nicht in der Gültigkeitsbereichskette gefunden wird, wird er zur Eigenschaft löschbar des globalen Objekts.

Nicht deklarierte Zuweisungen werfen eine ReferenceError auf ECMAScript 5 unter Strict Mode .

Muss man lesen:

Note: Diese Antwort wurde aus einer anderen Frage zusammengeführt, bei der der größte Zweifel und Missverständnis des OP bestand, dass mit einer FunctionDeclaration deklarierte Kennungen nicht überschrieben werden konnten, was nicht der Fall ist.

138
CMS

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

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

Bei der zweiten Variante (function functionTwo()) steht die Funktion für Code zur Verfügung, der oberhalb der Deklaration der Funktion ausgeführt wird.

Dies liegt daran, dass bei der ersten Variante die Funktion zur Laufzeit der Variablen foo zugewiesen wird. Im zweiten wird die Funktion dieser Kennung foo zur Analysezeit zugewiesen.

Weitere technische Informationen

JavaScript bietet drei Möglichkeiten, Funktionen zu definieren.

  1. Ihr erster Ausschnitt zeigt einen Funktionsausdruck . Dazu wird der Operator "function" verwendet, um eine Funktion zu erstellen. Das Ergebnis dieses Operators kann in einer beliebigen Variablen oder Objekteigenschaft gespeichert werden. Der Funktionsausdruck ist auf diese Weise mächtig. Der Funktionsausdruck wird häufig als "anonyme Funktion" bezeichnet, da er keinen Namen haben muss.
  2. Ihr zweites Beispiel ist eine Funktionsdeklaration . Dies verwendet die Anweisung "function", um eine Funktion zu erstellen. Die Funktion wird zur Analysezeit zur Verfügung gestellt und kann überall in diesem Bereich aufgerufen werden. Sie können es später noch in einer Variablen- oder Objekteigenschaft speichern.
  3. Die dritte Art, eine Funktion zu definieren, ist der Konstruktor "Function ()" , der in Ihrem ursprünglichen Beitrag nicht angezeigt wird. Es wird nicht empfohlen, dies zu verwenden, da es genauso funktioniert wie eval(), das seine Probleme hat.
116
thomasrutter

Eine bessere Erklärung für Gregs Antwort

functionTwo();
function functionTwo() {
}

Warum kein Fehler? Wir haben immer gelernt, dass Ausdrücke von oben nach unten ausgeführt werden (??)

Weil:

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

Dies bedeutet, dass der Code wie folgt lautet:

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

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

Aber bei Funktionsdeklarationen wird auch der gesamte Funktionskörper angehoben:

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

Andere Kommentatoren haben bereits den semantischen Unterschied der beiden oben genannten Varianten behandelt. Ich wollte einen stilistischen Unterschied feststellen: Nur die Variation "Zuweisung" kann eine Eigenschaft eines anderen Objekts festlegen.

Ich baue oft JavaScript-Module mit einem Muster wie folgt:

(function(){
    var exports = {};

    function privateUtil() {
            ...
    }

    exports.publicUtil = function() {
            ...
    };

    return exports;
})();

Bei diesem Muster verwenden alle Ihre öffentlichen Funktionen die Zuweisung, während Ihre privaten Funktionen die Deklaration verwenden.

(Beachten Sie auch, dass die Zuweisung nach der Anweisung ein Semikolon erfordern sollte, während die Deklaration dies verbietet.)

88
Sean McMillan

Ein Beispiel dafür, wann Sie die erste Methode der zweiten vorziehen sollten, ist, wenn Sie das Überschreiben der vorherigen Definitionen einer Funktion vermeiden müssen.

Mit

if (condition){
    function myfunction(){
        // Some code
    }
}

Diese Definition von myfunction setzt alle vorherigen Definitionen außer Kraft, da dies zur Analysezeit erfolgt.

Während

if (condition){
    var myfunction = function (){
        // Some code
    }
}

führt die korrekte Aufgabe aus, myfunction nur zu definieren, wenn condition erfüllt ist.

74
Mbengue Assane

Ein wichtiger Grund ist, eine einzige Variable als "Root" Ihres Namespaces hinzuzufügen ...

var MyNamespace = {}
MyNamespace.foo= function() {

}

oder

var MyNamespace = {
  foo: function() {
  },
  ...
}

Es gibt viele Techniken zum Namensraum. Mit der Fülle an verfügbaren JavaScript-Modulen wird dies immer wichtiger.

Siehe auch Wie deklariere ich einen Namespace in JavaScript?

60
Rob

Hoisting _ ​​ist die Aktion des JavaScript-Interpreters, bei der alle Variablen- und Funktionsdeklarationen an den Anfang des aktuellen Gültigkeitsbereichs verschoben werden. 

Es werden jedoch nur die eigentlichen Deklarationen angehoben. Zuordnungen werden dort belassen, wo sie sich befinden.

  • variablen/Funktionen, die innerhalb der Seite deklariert werden, sind global und können überall auf diese Seite zugreifen.
  • die innerhalb der Funktion deklarierten Funktionen der Variablen haben lokalen Gültigkeitsbereich. bedeutet, dass sie innerhalb des Funktionskörpers (Geltungsbereichs) verfügbar sind/abgerufen werden, sie sind außerhalb des Funktionskörpers nicht verfügbar.

Variable

Javascript wird als lose eingegebene Sprache bezeichnet. Dh, dass Javascript-Variablen den Wert eines beliebigen Data-Type enthalten können. Javascript sorgt automatisch dafür, dass der Variablentyp basierend auf dem zur Laufzeit bereitgestellten Wert/Literal geändert wird.

global_Page = 10;                                               var global_Page;      « undefined
    « Integer literal, Number Type.   -------------------       global_Page = 10;     « Number         
global_Page = 'Yash';                 |   Interpreted   |       global_Page = 'Yash'; « String
    « String literal, String Type.    «       AS        «       global_Page = true;   « Boolean 
var global_Page = true;               |                 |       global_Page = function (){          « function
    « Boolean Type                    -------------------                 var local_functionblock;  « undefined
global_Page = function (){                                                local_functionblock = 777;« Number
    var local_functionblock = 777;                              };  
    // Assigning function as a data.
};  

Funktion

function Identifier_opt ( FormalParameterList_opt ) { 
      FunctionBody | sequence of statements

      « return;  Default undefined
      « return 'some data';
}
  • funktionen, die innerhalb der Seite deklariert sind, werden an den Anfang der Seite mit globalem Zugriff gehoben.
  • funktionen, die innerhalb des Funktionsblocks deklariert wurden, werden an den Anfang des Blocks angehoben.
  • Standardrückgabewert der Funktion ist ' undefined ', Variable Deklaration Standardwert auch 'undefined'

    Scope with respect to function-block global. 
    Scope with respect to page undefined | not available.
    

Funktionserklärung

function globalAccess() {                                  function globalAccess() {      
}                                  -------------------     }
globalAccess();                    |                 |     function globalAccess() { « Re-Defined / overridden.
localAccess();                     «   Hoisted  As   «         function localAccess() {
function globalAccess() {          |                 |         }
     localAccess();                -------------------         localAccess(); « function accessed with in globalAccess() only.
     function localAccess() {                              }
     }                                                     globalAccess();
}                                                          localAccess(); « ReferenceError as the function is not defined

Funktionsausdruck

        10;                 « literal
       (10);                « Expression                (10).toString() -> '10'
var a;                      
    a = 10;                 « Expression var              a.toString()  -> '10'
(function invoke() {        « Expression Function
 console.log('Self Invoking');                      (function () {
});                                                               }) () -> 'Self Invoking'

var f; 
    f = function (){        « Expression var Function
    console.log('var Function');                                   f ()  -> 'var Function'
    };

Funktion, die der Variablen Beispiel zugewiesen wurde

(function selfExecuting(){
    console.log('IIFE - Immediately-Invoked Function Expression');
}());

var anonymous = function (){
    console.log('anonymous function Expression');
};

var namedExpression = function for_InternalUSE(fact){
    if(fact === 1){
        return 1;
    }

    var localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    //return; //undefined.
    return fact * for_InternalUSE( fact - 1);   
};

namedExpression();
globalExpression();

javascript interpretiert als

var anonymous;
var namedExpression;
var globalExpression;

anonymous = function (){
    console.log('anonymous function Expression');
};

namedExpression = function for_InternalUSE(fact){
    var localExpression;

    if(fact === 1){
        return 1;
    }
    localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    return fact * for_InternalUSE( fact - 1);    // DEFAULT UNDEFINED.
};

namedExpression(10);
globalExpression();

Sie können die Funktionsdeklaration und den Ausdruckstest über verschiedene Browser überprüfen, indem Sie jsperf Test Runner verwenden.


ES5 Constructor-Funktionsklassen : Funktionsobjekte, die mit Function.prototype.bind erstellt wurden

JavaScript behandelt Funktionen als erstklassige Objekte. Da Sie also ein Objekt sind, können Sie einer Funktion Eigenschaften zuweisen.

function Shape(id) { // Function Declaration
    this.id = id;
};
    // Adding a prototyped method to a function.
    Shape.prototype.getID = function () {
        return this.id;
    };
    Shape.prototype.setID = function ( id ) {
        this.id = id;
    };

var expFn = Shape; // Function Expression

var funObj = new Shape( ); // Function Object
funObj.hasOwnProperty('prototype'); // false
funObj.setID( 10 );
console.log( funObj.getID() ); // 10

ES6 führte Arrow-Funktion ein: Ein Pfeilfunktionsausdruck hat eine kürzere Syntax. Sie sind am besten für Nicht-Methodenfunktionen geeignet und können nicht als Konstruktoren verwendet werden.

ArrowFunction : ArrowParameters => ConciseBody .

const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; };
console.log( fn(2) ); // Even
console.log( fn(3) ); // Odd
52
Yash

Ich füge meine eigene Antwort hinzu, nur weil alle anderen den Hubteil gründlich abgedeckt haben.

Ich habe mich schon gefragt, welcher Weg schon lange besser ist, und dank http://jsperf.com jetzt weiß ich :)

enter image description here

Funktionsdeklarationen sind schneller, und das ist es, worauf es bei Web-Entwicklern wirklich ankommt? ;)

36
Leon Gaban

Eine Funktionsdeklaration und ein Funktionsausdruck, der einer Variablen zugewiesen ist, verhalten sich gleich, wenn die Bindung hergestellt ist.

Es gibt jedoch einen Unterschied, bei wie und wenn das Funktionsobjekt tatsächlich seiner Variablen zugeordnet ist. Dieser Unterschied ist auf den Mechanismus zurückzuführen, der in JavaScript als variables Heben bezeichnet wird.

Grundsätzlich werden alle Funktionsdeklarationen und Variablendeklarationen an den Anfang der function angehoben, in der die Deklaration auftritt (deshalb sagen wir, dass JavaScript Funktionsumfang hat).

  • Wenn eine Funktionsdeklaration angehoben wird, "folgt" der Funktionskörper Wenn der Funktionskörper ausgewertet wird, wird die Variable sofortbe an ein Funktionsobjekt gebunden.

  • Wenn eine Variablendeklaration angehoben wird, folgt die Initialisierung nicht , Wird jedoch "zurückgelassen". Die Variable wird am Anfang des Funktionshauptteils auf undefined initialisiert und erhält einen Wert an ihrer ursprünglichen Stelle im Code . (Tatsächlich wird an every ein Wert zugewiesen, an dem eine Variable mit demselben Namen deklariert wird.)

Die Reihenfolge beim Heben ist ebenfalls wichtig: Funktionsdeklarationen haben Vorrang vor Variablendeklarationen mit demselben Namen, und die letzte Funktionsdeklaration hat Vorrang vor vorherigen Funktionsdeklarationen mit demselben Namen.

Einige Beispiele...

var foo = 1;
function bar() {
  if (!foo) {
    var foo = 10 }
  return foo; }
bar() // 10

Die Variable foo wird an den Anfang der Funktion angehoben und mit undefined initialisiert, sodass !footrue ist und foo10 zugewiesen wird. Das foo außerhalb des Geltungsbereichs von bar spielt keine Rolle und bleibt unberührt. 

function f() {
  return a; 
  function a() {return 1}; 
  var a = 4;
  function a() {return 2}}
f()() // 2

function f() {
  return a;
  var a = 4;
  function a() {return 1};
  function a() {return 2}}
f()() // 2

Funktionsdeklarationen haben Vorrang vor Variablendeklarationen, und die letzte Funktionsdeklaration "klebt".

function f() {
  var a = 4;
  function a() {return 1}; 
  function a() {return 2}; 
  return a; }
f() // 4

In diesem Beispiel wird a mit dem Funktionsobjekt initialisiert, das sich aus der Auswertung der zweiten Funktionsdeklaration ergibt, und dann wird 4 zugewiesen.

var a = 1;
function b() {
  a = 10;
  return;
  function a() {}}
b();
a // 1

Hier wird zuerst die Funktionsdeklaration angehoben, die Variable a deklariert und initialisiert. Als Nächstes wird dieser Variablen 10 zugewiesen. Mit anderen Worten: Die Zuweisung ordnet die äußere Variable a nicht zu.

32
eljenso

Das erste Beispiel ist eine Funktionsdeklaration:

function abc(){}

Das zweite Beispiel ist ein Funktionsausdruck:

var abc = function() {};

Der Hauptunterschied besteht darin, wie sie angehoben (angehoben und deklariert) werden. Im ersten Beispiel wird die gesamte Funktionsdeklaration angehoben. Im zweiten Beispiel wird nur die Variable 'abc' angehoben, ihr Wert (die Funktion) ist undefiniert und die Funktion selbst bleibt an der Position, an der sie deklariert ist.

Einfach gesagt:

//this will work
abc(param);
function abc(){}

//this would fail
abc(param);
var abc = function() {}

Um mehr über dieses Thema zu erfahren, empfehle ich Ihnen dringend Folgendes link

30
sla55er

In Bezug auf die Codewartungskosten sind benannte Funktionen vorzuziehen:

  • Unabhängig von dem Ort, an dem sie deklariert werden (jedoch nach Umfang begrenzt).
  • Sie sind resistenter gegen Fehler wie die bedingte Initialisierung (Sie können sie trotzdem überschreiben, wenn Sie möchten).
  • Der Code wird lesbarer, indem lokale Funktionen getrennt von der Bereichsfunktion zugewiesen werden. Normalerweise geht die Funktionalität in diesem Bereich an erster Stelle, gefolgt von Deklarationen lokaler Funktionen.
  • In einem Debugger sehen Sie eindeutig den Funktionsnamen auf der Aufrufliste und nicht die Funktion "anonym/ausgewertet".

Ich vermute, dass weitere PROS für benannte Funktionen folgen. Was als Vorteil benannter Funktionen aufgeführt wird, ist für anonyme Funktionen ein Nachteil.

In der Vergangenheit waren anonyme Funktionen auf die Unfähigkeit von JavaScript als Sprache zurückzuführen, Mitglieder mit benannten Funktionen aufzulisten:

{
    member:function() { /* How do I make "this.member" a named function? */
    }
}
28
Sasha Firsov

Ich verwende den variablen Ansatz in meinem Code aus einem ganz bestimmten Grund, dessen Theorie oben abstrakt beschrieben wurde, aber ein Beispiel könnte einigen Leuten wie mir mit begrenztem JavaScript-Know-how helfen.

Ich habe Code, den ich mit 160 unabhängig entwickelten Brandings ausführen muss. Der größte Teil des Codes befindet sich in gemeinsam genutzten Dateien. Branding-spezifische Inhalte befinden sich jedoch in einer separaten Datei, eine für jedes Branding.

Einige Brandings erfordern bestimmte Funktionen, andere nicht. Manchmal muss ich neue Funktionen hinzufügen, um brandneue spezifische Dinge zu tun. Ich bin froh, den gemeinsam genutzten Code zu ändern, möchte aber nicht alle 160 Branding-Dateisätze ändern.

Mithilfe der Variablensyntax kann ich die Variable (im Wesentlichen einen Funktionszeiger) im gemeinsam genutzten Code deklarieren und entweder eine triviale Stub-Funktion zuweisen oder auf null setzen.

Die ein oder zwei Brandings, für die eine bestimmte Implementierung der Funktion erforderlich ist, können ihre Version der Funktion definieren und diese der Variablen zuweisen, wenn sie möchten, und der Rest tut nichts. Ich kann auf eine Nullfunktion testen, bevor ich sie im gemeinsam genutzten Code ausführen kann.

Aus den obigen Anmerkungen der Leute gehe ich hervor, dass es möglich ist, auch eine statische Funktion neu zu definieren, aber ich denke, die variable Lösung ist schön und klar.

24
Herc

In der Informatik sprechen wir über anonyme Funktionen und benannte Funktionen. Ich denke der wichtigste Unterschied ist, dass eine anonyme Funktion nicht an einen Namen gebunden ist, daher der Name anonyme Funktion. In JavaScript handelt es sich um ein Objekt der ersten Klasse, das zur Laufzeit dynamisch deklariert wird.

Weitere Informationen zu anonymen Funktionen und zum Lambda-Kalkül finden Sie in Wikipedia ( http://en.wikipedia.org/wiki/Anonymous_function ).

22
Kafka

Greg's Answer ist gut genug, aber ich möchte noch etwas hinzufügen, was ich gerade beim Ansehen von Douglas Crockfords videos gelernt habe.

Funktionsausdruck:

var foo = function foo() {};

Funktionsanweisung:

function foo() {};

Die Funktionsanweisung ist nur eine Abkürzung für var-Anweisung mit einem function-Wert.

So

function foo() {};

erweitert zu

var foo = function foo() {};

Die weiter ausdehnt auf:

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

Und beide werden an den Anfang des Codes angehoben.

Screenshot from video

22
Rohan

@EugeneLazutkin gibt ein Beispiel, in dem er eine zugewiesene Funktion benennt, um shortcut() als interne Referenz auf sich selbst verwenden zu können. John Resig gibt ein anderes Beispiel - Kopieren einer rekursiven Funktion, die einem anderen Objekt in seinem Learning Advanced Javascript Tutorial zugewiesen ist. Während das Zuweisen von Funktionen zu Eigenschaften nicht unbedingt die Frage ist, empfehle ich, das Tutorial aktiv auszuprobieren. Führen Sie den Code aus, indem Sie auf die Schaltfläche in der rechten oberen Ecke klicken und den Code doppelklicken, um ihn nach Belieben zu bearbeiten.

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

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 benennen, die rekursiv aufgerufen wird, 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." );
18
Joel Purra

Ein weiterer Unterschied, der in den anderen Antworten nicht erwähnt wird, besteht darin, dass Sie die anonyme Funktion verwenden

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

und verwende das als Konstruktor wie in

var one = new functionOne();

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

Mit 

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

der Name des Konstruktors kann als String mit two.constructor.name abgerufen werden.

16
Ingo Kegel

Die erste (Funktion doSomething (x)) sollte Teil einer Objektnotation sein.

Die zweite (var doSomething = function(x){ alert(x);}) erstellt einfach eine anonyme Funktion und weist sie einer Variablen doSomething zu. DoSomething () ruft also die Funktion auf.

Möglicherweise möchten Sie wissen, was eine Funktionsdeklaration und Funktionsausdruck ist.

Eine Funktionsdeklaration definiert eine benannte Funktionsvariable, ohne dass eine Variablenzuweisung erforderlich ist. Funktionsdeklarationen treten als eigenständige Konstrukte auf und können nicht in Funktionsblöcken verschachtelt werden.

function foo() {
    return 3;
}

ECMA 5 (13.0) definiert die Syntax als 
Funktionskennung (FormalParameterList.)opt ) {Funktionskörper}

In obiger Bedingung ist der Funktionsname innerhalb seines Gültigkeitsbereichs und des Gültigkeitsbereichs des übergeordneten Elements sichtbar (sonst wäre er nicht erreichbar).

Und in einem Funktionsausdruck

Ein Funktionsausdruck definiert eine Funktion als Teil einer größeren Ausdruckssyntax (normalerweise eine Variablenzuweisung). Funktionen, die über Funktionsausdrücke definiert werden, können benannt oder anonym sein. Funktionsausdrücke sollten nicht mit "Funktion" beginnen.

// Anonymous function expression
var a = function() {
    return 3;
}

// Named function expression
var a = function foo() {
    return 3;
}

// Self-invoking function expression
(function foo() {
    alert("hello!");
})();

ECMA 5 (13.0) definiert die Syntax als 
Funktionskennungopt (FormalParameterListopt ) {Funktionskörper}

14
NullPoiиteя

Wenn Sie diese Funktionen zum Erstellen von Objekten verwenden würden, würden Sie Folgendes erhalten:

var objectOne = new functionOne();
console.log(objectOne.__proto__); // prints "Object {}" because constructor is an anonymous function

var objectTwo = new functionTwo();
console.log(objectTwo.__proto__); // prints "functionTwo {}" because constructor is a named function
14
Pawel Furmaniak

Ich liste die Unterschiede unten auf:

  1. Eine Funktionsdeklaration kann an beliebiger Stelle im Code platziert werden. Selbst wenn es aufgerufen wird, bevor die Definition im Code erscheint, wird sie ausgeführt, wenn die Funktionsdeklaration in den Speicher geschrieben oder auf eine Weise angehoben wird, bevor ein anderer Code auf der Seite mit der Ausführung beginnt.

    Schauen Sie sich die Funktion unten an:

    function outerFunction() {
        function foo() {
           return 1;
        }
        return foo();
        function foo() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 2
    

    Dies liegt daran, dass es während der Ausführung wie folgt aussieht:

    function foo() {  // The first function declaration is moved to top
        return 1;
    }
    function foo() {  // The second function declaration is moved to top
        return 2;
    }
    function outerFunction() {
        return foo();
    }
    alert(outerFunction()); //So executing from top to bottom,
                            //the last foo() returns 2 which gets displayed
    

    Wenn ein Funktionsausdruck vor dem Aufruf nicht definiert wurde, führt dies zu einem Fehler. Auch hier wird die Funktionsdefinition selbst nicht nach oben verschoben oder wie in den Funktionsdeklarationen in den Speicher geschrieben. Die Variable, der wir die Funktion zuweisen, wird jedoch angehoben und undefined wird ihr zugewiesen.

    Gleiche Funktion mit Funktionsausdrücken:

    function outerFunction() {
        var foo = function() {
           return 1;
        }
        return foo();
        var foo = function() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 1
    

    Dies liegt daran, dass es während der Ausführung so aussieht:

    function outerFunction() {
       var foo = undefined;
       var foo = undefined;
    
       foo = function() {
          return 1;
       };
       return foo ();
       foo = function() {   // This function expression is not reachable
          return 2;
       };
    }
    alert(outerFunction()); // Displays 1
    
  2. Es ist nicht sicher, Funktionsdeklarationen in Nichtfunktionsblöcken wie if zu schreiben, da sie nicht zugänglich sind.

    if (test) {
        function x() { doSomething(); }
    }
    
  3. Ein benannter Funktionsausdruck wie der unten stehende funktioniert möglicherweise nicht in Internet Explorer-Browsern vor Version 9.

    var today = function today() {return new Date()}
    
14
varna

??????????????????? ???????????? ??????????????? ???????????????????????????????????????? ?????????????????????????????????????????? ?????????????????????????? ???????????? ???????????? ????????????????????????????????? ??????????????????????????????????????????? ???????? ????????????????????????????????? ???????? ??????????????????????? ???????????????????.

  1. Verfügbarkeit (Umfang) der Funktion

Das Folgende funktioniert, weil function add() auf den nächsten Block beschränkt ist:

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

function add(a, b){
  return a + b;
}

Folgendes funktioniert nicht (da var add= Die Funktion function add() ersetzt).

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function add(a, b){
  return a + b;
}

Das Folgende funktioniert nicht, da add nach seiner Verwendung deklariert wird.

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function(a, b){
  return a + b;
}
  1. (Funktion) . name

Der Name einer Funktion function thefuncname(){} ist der Funktionsname , wenn er auf diese Weise deklariert wird.

function foobar(a, b){}

console.log(foobar.name);
var a = function foobar(){};

console.log(a.name);

Andernfalls, wenn eine Funktion als function(){} deklariert ist, ist der function . Name die erste Variable, die zum Speichern der Funktion verwendet wird.

var a = function(){};
var b = (function(){ return function(){} });

console.log(a.name);
console.log(b.name);

Wenn für die Funktion keine Variablen festgelegt sind, ist der Funktionsname die leere Zeichenfolge ("").

console.log((function(){}).name === "");

Während die Variable, der die Funktion zugewiesen ist, anfänglich den Namen festlegt, ändern aufeinanderfolgende Variablen, die für die Funktion festgelegt wurden, den Namen nicht.

var a = function(){};
var b = a;
var c = b;

console.log(a.name);
console.log(b.name);
console.log(c.name);
  1. Performance

In Googles V8 und Firefoxs Spidermonkey gibt es möglicherweise einen JIST-Kompilierungsunterschied von einigen Mikrosekunden, aber letztendlich ist das Ergebnis genau dasselbe. Um dies zu beweisen, untersuchen wir die Effizienz von JSPerf bei Mikrobenchmarks, indem wir die Geschwindigkeit zweier leerer Codeausschnitte vergleichen. Die JSPerf-Tests finden Sie hier . Und die jsben.ch Tests sind hier zu finden . Wie Sie sehen, gibt es einen merklichen Unterschied, wann es keinen geben sollte. Wenn Sie wirklich ein Performance-Freak wie ich sind, lohnt es sich möglicherweise, die Anzahl der Variablen und Funktionen im Gültigkeitsbereich zu verringern und insbesondere den Polymorphismus zu beseitigen (z. B. die Verwendung derselben Variablen zum Speichern von zwei verschiedenen Typen).

  1. Variable Veränderbarkeit

Wenn Sie zum Deklarieren einer Variablen das Schlüsselwort var verwenden, können Sie der Variablen wie folgt einen anderen Wert zuweisen.

(function(){
    "use strict";
    var foobar = function(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

Wenn wir jedoch die const-Anweisung verwenden, wird die Variablenreferenz unveränderlich. Dies bedeutet, dass wir der Variablen keinen neuen Wert zuweisen können. Beachten Sie jedoch, dass dadurch der Inhalt der Variablen nicht unveränderlich wird: Wenn Sie const arr = [] Ausführen, können Sie arr[10] = "example" Dennoch ausführen. Nur etwas wie arr = "new value" Oder arr = [] Zu tun, würde einen Fehler auslösen, wie unten gezeigt.

(function(){
    "use strict";
    const foobar = function(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

Interessanterweise ist, wenn wir die Variable als function funcName(){} deklarieren, die Unveränderlichkeit der Variablen dieselbe wie die Deklaration mit var.

(function(){
    "use strict";
    function foobar(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

??????????????? ???????? ???????????? "????????????????????????? ?????????????????????"

Der "nächste Block" ist die nächste "Funktion" (einschließlich Asynchronfunktionen, Generatorfunktionen und Asynchrongeneratorfunktionen). Interessanterweise verhält sich eine function functionName() {} jedoch wie eine var functionName = function() {}, wenn sie sich in einem Nicht-Abschlussblock für Elemente außerhalb des Abschlusses befindet. Beobachten.

  • Normal var add=function(){}
try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}');
  }
} catch(e) {
  console.log("Is a block");
}
var add=function(a, b){return a + b}
  • Normal function add(){}
try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
function add(a, b){
  return a + b;
}
  • Funktion
try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(function () {
    function add(a, b){
      return a + b;
    }
})();
  • Anweisung (wie if, else, for, while, try/catch/finally, switch, do/while, with)
try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
{
    function add(a, b){
      return a + b;
    }
}
  • Pfeilfunktion mit var add=function()
try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    var add=function(a, b){
      return a + b;
    }
})();
  • Pfeilfunktion Mit function add()
try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    function add(a, b){
      return a + b;
    }
})();
12
Jack Giffin

Moderne JavaScript-Engines sind angesichts des Arguments "benannte Funktionen werden in Stapelverfolgungen sichtbar" durchaus in der Lage, anonyme Funktionen darzustellen.

Zum jetzigen Zeitpunkt beziehen sich V8, SpiderMonkey, Chakra und Nitro immer auf benannte Funktionen. Sie beziehen sich fast immer auf eine anonyme Funktion anhand ihrer Kennung, falls vorhanden.

SpiderMonkey kann den Namen einer anonymen Funktion ermitteln, die von einer anderen Funktion zurückgegeben wird. Der Rest kann nicht.

Wenn Sie wirklich wollten, dass Ihre Iterator- und Erfolgs-Callbacks in der Ablaufverfolgung angezeigt werden, könnten Sie diese auch nennen ...

[].forEach(function iterator() {});

Aber zum größten Teil ist es nicht wert, betont zu werden.

Geschirr ( Fiddle )

'use strict';

var a = function () {
    throw new Error();
},
    b = function b() {
        throw new Error();
    },
    c = function d() {
        throw new Error();
    },
    e = {
        f: a,
        g: b,
        h: c,
        i: function () {
            throw new Error();
        },
        j: function j() {
            throw new Error();
        },
        k: function l() {
            throw new Error();
        }
    },
    m = (function () {
        return function () {
            throw new Error();
        };
    }()),
    n = (function () {
        return function n() {
            throw new Error();
        };
    }()),
    o = (function () {
        return function p() {
            throw new Error();
        };
    }());

console.log([a, b, c].concat(Object.keys(e).reduce(function (values, key) {
    return values.concat(e[key]);
}, [])).concat([m, n, o]).reduce(function (logs, func) {

    try {
        func();
    } catch (error) {
        return logs.concat('func.name: ' + func.name + '\n' +
                           'Trace:\n' +
                           error.stack);
        // Need to manually log the error object in Nitro.
    }

}, []).join('\n\n'));

V8

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at e.i (http://localhost:8000/test.js:17:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: j
Trace:
Error
    at j (http://localhost:8000/test.js:20:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: l
Trace:
Error
    at l (http://localhost:8000/test.js:23:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at http://localhost:8000/test.js:28:19
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: n
Trace:
Error
    at n (http://localhost:8000/test.js:33:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: p
Trace:
Error
    at p (http://localhost:8000/test.js:38:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27 test.js:42

Spinnenaffe

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
[email protected]://localhost:8000/test.js:17:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: j
Trace:
[email protected]://localhost:8000/test.js:20:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: l
Trace:
[email protected]://localhost:8000/test.js:23:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
m</<@http://localhost:8000/test.js:28:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: n
Trace:
[email protected]://localhost:8000/test.js:33:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: p
Trace:
[email protected]://localhost:8000/test.js:38:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1

Chakra

func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at e.i (http://localhost:8000/test.js:17:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at j (http://localhost:8000/test.js:20:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at l (http://localhost:8000/test.js:23:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at Anonymous function (http://localhost:8000/test.js:28:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at n (http://localhost:8000/test.js:33:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at p (http://localhost:8000/test.js:38:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)

Nitro

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
[email protected]://localhost:8000/test.js:17:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: j
Trace:
[email protected]://localhost:8000/test.js:20:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: l
Trace:
[email protected]://localhost:8000/test.js:23:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
http://localhost:8000/test.js:28:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: n
Trace:
[email protected]://localhost:8000/test.js:33:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: p
Trace:
[email protected]://localhost:8000/test.js:38:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33
12
Jackson

In JavaScript gibt es zwei Möglichkeiten, Funktionen zu erstellen:

  1. Funktionsdeklaration:

    function fn(){
      console.log("Hello");
    }
    fn();
    

    Dies ist sehr einfach, selbsterklärend, wird in vielen Sprachen verwendet und ist in der gesamten C-Sprachfamilie Standard. Wir haben eine Funktion als definiert deklariert und durch Aufruf ausgeführt.

    Sie sollten wissen, dass Funktionen eigentlich Objekte in JavaScript sind. intern haben wir ein Objekt für die obige Funktion erstellt und ihm einen Namen namens fn gegeben oder die Referenz auf das Objekt wird in fn gespeichert. Funktionen sind Objekte in JavaScript. Eine Instanz einer Funktion ist eigentlich eine Objektinstanz.

  2. Funktionsausdruck:

    var fn=function(){
      console.log("Hello");
    }
    fn();
    

    JavaScript verfügt über erstklassige Funktionen, dh Sie erstellen eine Funktion und weisen sie einer Variablen zu, genauso wie Sie einen String oder eine Zahl erstellen und einer Variablen zuweisen. Hier wird die Variable fn einer Funktion zugewiesen. Der Grund für dieses Konzept ist, dass Funktionen Objekte in JavaScript sind. fn zeigt auf die Objektinstanz der obigen Funktion. Wir haben eine Funktion initialisiert und einer Variablen zugewiesen. Die Funktion wird nicht ausgeführt und das Ergebnis zugewiesen.

Referenz: JavaScript-Funktionsdeklarationssyntax: var fn = function () {} vs Funktion fn () {}

10
Anoop Rai

Beides sind verschiedene Arten, eine Funktion zu definieren. Der Unterschied besteht darin, wie der Browser sie interpretiert und in einen Ausführungskontext lädt. 

Der erste Fall betrifft Funktionsausdrücke, die nur geladen werden, wenn der Interpreter diese Codezeile erreicht. Wenn Sie also Folgendes tun, erhalten Sie die Fehlermeldung, dass das functionOne keine Funktion ist .

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

Der Grund ist, dass in der ersten Zeile functionOne kein Wert zugewiesen wird und daher undefiniert ist. Wir versuchen, es als Funktion zu bezeichnen, und daher erhalten wir einen Fehler.

In der zweiten Zeile weisen wir functionOne die Referenz einer anonymen Funktion zu.

Der zweite Fall betrifft Funktionsdeklarationen, die geladen werden, bevor Code ausgeführt wird. Wenn Sie also Folgendes mögen, erhalten Sie keine Fehler, wenn die Deklaration vor der Codeausführung geladen wird.

functionOne();
function functionOne() {
   // Some code
}
8
Nitin9791

Über die Leistung:

Neue Versionen von V8 führten mehrere Optimierungen unter der Haube ein und auch SpiderMonkey.

Es gibt fast keinen Unterschied zwischen Ausdruck und Deklaration. 
Funktionsausdruck scheint schneller zu sein jetzt.

Chrome 62.0.3202 Chrome test

FireFox 55 Firefox test

Chrome Canary 63.0.3225 Chrome Canary test


Anonymous Funktionsausdrücke scheinen eine bessere Leistung zu haben gegen Named Funktionsausdruck.


Feuerfuchs Firefox named_anonymous Chrome Canary Chrome canary named_anonymous Chrom Chrome named_anonymous

8
Panos Kal.

Sie sind sich mit einigen kleinen Unterschieden ziemlich ähnlich. Die erste ist eine Variable, die einer anonymen Funktion (Funktionsdeklaration) zugewiesen ist, und die zweite ist der normale Weg, um eine Funktion in JavaScript zu erstellen (anonyme Funktionsdeklaration). Beide haben Verwendung, Vor- und Nachteile :

1. Funktionsausdruck

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

Ein Funktionsausdruck definiert eine Funktion als Teil eines größeren Ausdruckssyntax (normalerweise eine Variablenzuweisung). Funktionen über Funktionen definiert Ausdrücke können benannt oder anonym sein. Funktion Ausdrücke dürfen nicht mit "function" beginnen (daher die Klammern Um das selbstaufrufende Beispiel unten).

Wenn Sie einer Funktion eine Variable zuweisen, bedeutet dies kein Hoisting, da wir wissen, dass Funktionen in JavaScript Hoist sind, können sie aufgerufen werden, bevor sie deklariert werden, während Variablen deklariert werden müssen, bevor Sie auf sie zugreifen können. In diesem Fall bedeutet dies nicht Greifen Sie auf die Funktion zu, wo sie deklariert wurde. Außerdem könnte es eine Möglichkeit sein, Ihre Funktionen zu schreiben. Für die Funktionen, die eine andere Funktion zurückgeben, könnte diese Art der Deklaration sinnvoll sein. Auch in ECMA6 und oben können Sie diese Funktion einer Pfeilfunktion zuordnen kann verwendet werden, um anonyme Funktionen aufzurufen. Auch diese Deklarationsmethode ist eine bessere Methode, Constructor-Funktionen in JavaScript zu erstellen.

2. Funktionserklärung

function functionTwo() {
    // Some code
}

Eine Funktionsdeklaration definiert eine benannte Funktionsvariable ohne variable Zuordnung erforderlich. Funktionsdeklarationen treten als .__ auf. Standalone-Konstrukte und können nicht in Nichtfunktionsblöcken geschachtelt werden . Es ist hilfreich, sie als Geschwister von Variablendeklarationen zu betrachten. Genau wie Variablendeklarationen mit „var“ beginnen müssen, muss Function Deklarationen müssen mit "Funktion" beginnen.

Dies ist die normale Art, eine Funktion in JavaScript aufzurufen. Diese Funktion kann aufgerufen werden, noch bevor Sie sie deklarieren, da in JavaScript alle Funktionen Hoisted werden. Wenn Sie jedoch 'use strict' verwenden, wird dies nicht wie erwartet Hoist, sondern eine gute Methode alle normalen Funktionen aufzurufen, die keine großen Zeilen haben und keine Konstruktorfunktion sind.

Wenn Sie weitere Informationen zur Funktionsweise von Hebezeugen in JavaScript benötigen, besuchen Sie den folgenden Link:

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

7
Alireza

Dies ist nur zwei Möglichkeiten, Funktionen zu deklarieren, und zweitens können Sie die Funktion vor der Deklaration verwenden.

5
Tao

new Function() kann verwendet werden, um den Rumpf der Funktion in einer Zeichenfolge zu übergeben. Und damit können dynamische Funktionen erstellt werden. Weitergabe des Skripts, ohne das Skript auszuführen.

var func = new Function("x", "y", "return x*y;");
function secondFunction(){
   var result;
   result = func(10,20);
   console.log ( result );
}

secondFunction()
4
SuperNova

Dies wird als Funktionsausdruck bezeichnet:

var getRectArea = function(width, height) {
    return width * height;
};

console.log("Area of Rectangle: " + getRectArea(3,4));
// This should return the following result in the console: 
// Area of Rectangle: 12

Dies wird als Funktionsdeklaration bezeichnet:

var w = 5;
var h = 6;

function RectArea(width, height) {  //declaring the function
  return area = width * height;
}                                   //note you do not need ; after }

RectArea(w,h);                      //calling or executing the function
console.log("Area of Rectangle: " + area);
// This should return the following result in the console: 
// Area of Rectangle: 30

Ich hoffe, dies hilft zu erklären, was der Unterschied zwischen Funktionsausdruck und Funktionsdeklaration ist und wie sie verwendet werden. Vielen Dank.

1
Kean Amaral

Differenzfunktionsdeklaration und Funktionsausdruck:

Javascript hat erstklassige Funktionen. Dies bedeutet, dass sie wie jede andere Variable behandelt werden können. Funktionen können als Argumente in einer Funktion übergeben, von einer Funktion zurückgegeben werden nd können in Variablen gespeichert werden.

Das Speichern einer Funktion in einer Variablen (Funktionsausdruck) ist jedoch nicht die einzige Möglichkeit, eine Funktion zu erstellen. Dies kann auch über eine Funktionsdeklaration erfolgen. Hier sind die wichtigsten Unterschiede:

  1. Funktionsausdrücke können anonym sein, während eine Funktionsdeklaration einen Namen haben muss.
  2. Beide haben eine Namenseigenschaft, mit der die Funktion identifiziert wird. Die Eigenschaft name eines Funktionsausdrucks ist der Name der Variablen, an die er gebunden ist, während der Name einer Funktionsdeklaration einfach der angegebene Name ist.
  3. Funktionsdeklarationen werden angehoben, Funktionsausdrücke nicht. Nur die Variable wird auf den Wert undefined gesetzt.

Hier ist ein Beispiel:

try {
  functionOne();
} catch (e) {
  console.log('i cant run because im not hoisted');
}

functionTwo();

// function expression, does not get hoisted
let functionOne = function randomName() {
    // Some code
};

// function declaration, gets hoisted
function functionTwo() {
   console.log('I get hoisted');
}

try {
  randomName(); // this isn't the proper name, it is functionOne
} catch (e) {
  console.log('You cant call me with randomName my name is function one');
}

:

0

Ausdruck in JS : Etwas, das einen Wert zurückgibt 
Beispiel: Probieren Sie folgendes in Chrome aus:

a = 10
output : 10

(1 + 3)
output = 4

Deklaration/Statement : Etwas, das keinen Wert zurückgibt 
Beispiel:

if (1 > 2) {
 // do something. 
}

hier (1> 2) ist ein Ausdruck, aber das "if" -Statament nicht. Es gibt nichts zurück. 


In ähnlicher Weise haben wir Funktionsdeklaration/Anweisung vs. Funktionsausdruck 
Nehmen wir ein Beispiel:

// test.js

var a = 10;

// function expression
var fun_expression = function() {
   console.log("Running function Expression");
}

// funciton expression

function fun_declaration() {
   console.log("Running function Statement");
}

Wichtig: Was passiert, wenn JavaScript-Engines die obige js-Datei ausführen.

  • Wenn dieses js läuft, werden folgende Dinge passieren:

    1. Der Speicher wird mit den Variablen 'a' und 'fun_expression' erstellt. Für die Funktionsanweisung 'fun_declaration' wird ein Speicher erstellt.
    2. 'a' wird 'undefined' zugewiesen. 'fun_expression' wird 'undefined' zugewiesen. 'fun_declaration' wird vollständig im Speicher gespeichert. 
      Hinweis: Die obigen Schritte 1 und 2 werden als 'Ausführungskontext - Erstellungsphase' bezeichnet. 

Nehmen wir an, wir aktualisieren die js auf.

// test.js

console.log(a)  //output: udefined (No error)
console.log(fun_expression)  // output: undefined (No error)
console.log(fun_expression()) // output: Error. As we trying to invoke undefined. 
console.log(fun_declaration()) // output: running function statement  (As fun_declaration is already hoisted in the memory). 

var a = 10;

// function expression
var fun_expression = function() {
   console.log('Running function expression')
}

// function declaration

function fun_declaration() {
   console.log('running function declaration')
}

console.log(a)   // output: 10
console.log(fun_expression()) //output: Running function expression
console.log(fun_declaration()) //output: running function declaration

Die oben in den Kommentaren erwähnte Ausgabe sollte hilfreich sein, um die Unterschiede zwischen Funktionsausdruck und Funktionsanweisung/Deklaration zu verstehen.

0
Santosh Pillai

Ein wichtiger Punkt, der zu beachten ist, ist:

es gibt zwei Funktionen: -

sum(1,2);

const sum = function(first, second) {
  return first + second;
}

Im obigen Fall wird ein Fehler ausgegeben, dass die Summe nicht definiert ist, sondern

sum(1,2);

function sum(first, second) {
  return first + second;
}

Diese Funktion führt zu keinem Fehler, da in diesem Fall function hoisting ausgeführt wird.

0
Nitesh Ranjan

Benannte Funktionen vs. anonyme Funktionen

Anonyme Funktionsausdrücke sind schnell und einfach zu tippen, und viele Bibliotheken und Werkzeuge neigen dazu, diesen idiomatischen Codestil zu fördern. Sie haben jedoch mehrere Nachteile zu beachten:

  1. Anonyme Funktionen können in Stack-Traces nicht angezeigt werden, was das Debuggen erschweren kann.
  2. Ohne Namen, wenn sich die Funktion auf sich selbst beziehen muss, für Rekursion usw.
  3. Anonyme Funktionen lassen einen Namen aus, der zu weniger lesbarem Code führen kann.

Benennen von Funktionsausdrücken

Die Angabe eines Namens für Ihren Funktionsausdruck behebt alle diese Nachteile sehr effektiv und hat keine spürbaren Nachteile. Am besten benennen Sie Ihre Funktionsausdrücke immer:

setTimeout(function timeHandler() { // <-- named function here!
  console.log('I've waited 1 second');
}, 1000);

Benennen des sofort aufgerufenen Funktionsausdrucks (IIFE): 

var a = 42;

(function IIFE(global) { // <-- named IIFEs!
  console.log(global.a); // 42
})(window);

Hinweis: Bei Funktionen, die einer Variablen zugewiesen sind, ist die Benennung der Funktion in diesem Fall nicht sehr verbreitet und kann zu Verwirrung führen. In diesem Fall ist es besser, die Pfeilfunktion zu verwenden.

0
Shakespear

Ich bevorzuge es, Funktion als Variable zu definieren:

let first = function(x){
   return x[0];
}

Anstatt:

function first(){
    ....
}

Weil ich beim Definieren der Funktion Ausdrücke und Dekoratoren verwenden kann. Zum Beispiel:

let safe = function(f){
  try {f()...}
}
let last = safe(function(x){return x[0]}).

Auch mit ES6 ist es viel kürzer:

 let last = x => x[0]
 ...........
 function last(x){
     return x[0];
 }
......

let last = safe(x => x[0]);
0
user2693928

Ein weiterer Unterschied zwischen beiden Funktionen ist, dass functionOne als Variable verwendet werden kann, die mehrere Funktionen enthalten kann, und functionTwo einen Codeblock enthält, der beim Aufruf alle ausgeführt wird. Bitte überprüfen Sie unten :

   var functionOne = (function() {
      return {

         sayHello: function(){
                console.log('say hello')

         },
         redirectPage:function(_url){
                window.location.href = _url;
         }

      }
})();

Sie haben die Wahl, welche Funktion aufgerufen werden soll. z. B. functionOne.sayHello oder functionOne. redirectPage. Und wenn Sie functionTwo aufrufen, wird der gesamte Codeblock ausgeführt.

0
H.Ostwal