Var Funktionsname = Funktion () {} vs Funktion Funktionsname () {}

Vor kurzem unterstützte ich den JavaScript-Code eines anderen Benutzers. Ich korrigiere Fehler, füge Funktionen hinzu und versuche auch, den Code aufzuräumen und ihn einheitlicher zu gestalten.

Der vorherige Entwickler verwendet zwei Möglichkeiten, 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 welche Vor- und Nachteile haben sie jeweils? Gibt es etwas, das mit einer Methode möglich ist, mit einer anderen Methode nicht?

6296
03 дек. Richard Garside fragte am 03.12 2008-12-03 14:31 08 um 14:31 Uhr 2008-12-03 14:31
@ 37 Antworten
  • 1
  • 2

Der Unterschied ist, dass functionOne ein Ausdruck einer Funktion ist und daher nur bestimmt wird, wenn diese Zeile erreicht ist, während functionTwo eine Funktionsdeklaration ist und festgelegt wird, sobald die umgebende Funktion oder das Skript ausgeführt wird (aufgrund des Abhebens ).

Zum Beispiel die Ausdrucksfunktion:

 // 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 vom test - es sei denn, die use strict Aktion wird verwendet. In diesem Fall wird einfach ein Fehler verursacht.

4669
03 дек. Antwort von Greg 03 Dez. 2008-12-03 14:37 08 um 14:37 Uhr 2008-12-03 14:37

Zuerst möchte ich Greg function abc(){} : function abc(){} ebenfalls begrenzt - 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 können Sie beide Stile kombinieren:

 var xyz = function abc(){}; 

xyz wird wie üblich definiert, abc - in allen Browsern undefiniert, aber Internet Explorer - hängt nicht von seiner Definition ab. Aber er wird in seinem Körper definiert sein:

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

Wenn Sie in allen Browsern Pseudonyme verwenden möchten, verwenden Sie diesen Anzeigentyp:

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

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

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

Einer der zwingenden Gründe für die Verwendung des kombinierten Stils ist das "name" -Attribut für Funktionsobjekte ( nicht von Internet Explorer unterstützt ). Grundsätzlich, wenn Sie eine Funktion wie definieren

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

Sein Name wird automatisch vergeben. Aber wenn Sie es als definieren

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

Der Name ist leer. Wir haben eine anonyme Funktion erstellt und dieser eine Variable zugewiesen.

Ein weiterer guter Grund für die Verwendung des kombinierten Stils ist die Verwendung eines kurzen internen Namens, um auf ihn zu verweisen, wobei ein >

 // 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 dem externen Namen tun, aber es wird zu umständlich (und >

(Eine andere Möglichkeit, sich selbst anzusprechen, ist die Verwendung von arguments.callee , die noch relativ >

Down behandelt beide Anweisungen unterschiedlich. Dies ist eine Funktionsdeklaration:

border=0
 function abc(){} 

abc hier ist überall im aktuellen Bereich definiert:

 // We can call it here abc(); // Works // Yet, it is defined down there. function abc(){} // We can call it again abc(); // Works 

Darüber hinaus stieg er mit der return :

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

Dies ist ein Funktionsausdruck:

 var xyz = function(){}; 

xyz wird hier vom Ziel aus definiert:

 // We can't call it here xyz(); // UNDEFINED!!! // Now it is defined xyz = function(){} // We can call it here xyz(); // works 

Die Funktionsdeklaration und der Funktionsausdruck sind der wahre Grund dafür, dass es einen Unterschied gibt, wie Greg zeigt.

Spaß Fakt:

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

Ich persönlich bevorzuge die Deklaration "expression of function", da ich auf diese Weise die Sichtbarkeit steuern kann. Wenn ich eine Typfunktion definiere

 var abc = function(){}; 

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

 abc = function(){}; 

Ich weiß, dass ich es global definiert habe, was bedeutet, dass ich abc nirgendwo in der Kette von Regionen definiert habe. Dieser Definitionsstil ist stabil, auch wenn er in eval() . Obwohl die Definition

 function abc(){}; 

hängt vom Kontext ab und kann Sie fragen, wo es definiert ist, insbesondere bei eval() - Antwort: Kommt auf den Browser an.

1846
03 дек. Die Antwort wird von Eugene Lazutkin 03 Dez. Gegeben . 2008-12-03 20:43 08 um 20:43 Uhr 2008-12-03 20:43

Hier ist eine Zusammenfassung der Standardformulare, die Funktionen erstellen: (Ursprünglich für eine andere Frage geschrieben, jedoch nach dem Übergang zur kanonischen Frage angepasst.)

Bedingungen:

Schnelle Liste:

  • Funktionsdeklaration

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

  • Benannte function Ausdruck

  • Access Function Initializer (ES5 +)

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

  • Methodendeklaration im Objektinitialisierer (ES2015 +)

  • Konstruktor- und Methodendeklarationen in der class (ES2015 +)

Funktionsdeklaration

Das erste Formular ist eine Funktionsdeklaration, die folgendermaßen aussieht:

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

Eine Funktionsdeklaration ist eine Anzeige. Es ist keine Aussage oder Ausdruck. Du folgst ihm also nicht mit ; (obwohl es harmlos ist).

Eine Funktionsdeklaration wird verarbeitet, wenn die Ausführung in den Kontext eintritt, in dem sie vor dem Ausführen eines Schrittcodes erscheint. Der von ihr erstellten Funktion wird ein eigener Name zugewiesen (im obigen Beispiel x ), und dieser Name wird in dem Bereich platziert, in dem die Deklaration angezeigt wird.

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

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

Vor ES2015 wurde in der Spezifikation nicht erläutert, was die JavaScript-Engine tun soll, wenn Sie eine Funktionsdeklaration in eine Kontrollstruktur einfügen. Versuchen Sie beispielsweise, if , switch , while usw. Zum Beispiel:

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

Da sie vor der Ausführung des Schritt-für-Schritt-Codes verarbeitet werden, ist es schwierig zu wissen, was zu tun ist, wenn sie sich in der Verwaltungsstruktur befinden.

Obwohl es nicht vor ES2015 angegeben wurde, war es eine gültige Erweiterung zur Unterstützung von Funktionsdeklarationen in Blöcken. Leider (und unausweichlich) haben verschiedene Motoren unterschiedliche Dinge getan.

Ab ES2015 wird in der Spezifikation angegeben, was zu tun ist. In der Tat gibt es drei verschiedene Aktionen:

  1. Wenn sich der freie Modus nicht im Webbrowser befindet, sollte die JavaScript-Engine etwas tun.
  2. Im freien Modus in einem Webbrowser muss die JavaScript-Engine etwas anderes tun.
  3. Im strikten Modus (Browser oder nicht) sollte die JavaScript-Engine noch etwas tun.

Die Regeln für den freien Modus sind schwierig, aber im strikten Modus sind die Funktionsdeklarationen in den Blöcken einfach: Sie sind lokal für den Block (sie haben den Blockbereich, der in ES2015 ebenfalls neu ist) und gehen bis zum Block. Also:

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

Ausdruck "anonyme" function

Die zweite allgemeine Form wird anonymer Funktionsausdruck genannt:

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

Wie alle Ausdrücke wird es beim Erreichen der schrittweisen Codeausführung berechnet.

In ES5 hat die zu erstellende Funktion keinen Namen (sie ist anonym). In ES2015 wird einer Funktion, wann immer möglich, ein Name zugewiesen, der den Kontext verlässt. Im obigen Beispiel lautet der Name y . So etwas passiert, wenn die Funktion der Wert des Eigenschaftsinitialisierers ist. (Weitere Informationen zum Zeitpunkt und zu den Regeln finden SetFunctionName in der Spezifikation unter SetFunctionName Sie wird überall angezeigt.)

Benannte function Ausdruck

Die dritte Form ist ein Ausdruck mit einer benannten Funktion ("NFE"):

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

Die von ihr erstellte Funktion hat einen eigenen Namen (in diesem Fall w ). Wie alle Ausdrücke wird dies ausgewertet, wenn die Codeausführung Schritt für Schritt ausgeführt wird. Der Funktionsname wird nicht zu dem Bereich hinzugefügt, in dem der Ausdruck angezeigt wird. Der Name liegt im Bereich der Funktion selbst:

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

Bitte beachten Sie, dass NFEs häufig eine Fehlerquelle für JavaScript-Implementierungen sind. Beispielsweise behandeln IE8 und frühere Versionen NFE völlig falsch und erstellen zwei unterschiedliche Funktionen zu zwei verschiedenen Zeitpunkten. Frühe Versionen von Safari hatten auch Probleme. Die gute Nachricht ist, dass solche Probleme in aktuellen Browser-Versionen (IE9 und höher, die aktuelle Safari) nicht mehr existieren. (Leider ist IE8 zum Zeitpunkt der Erstellung dieses Dokuments immer noch weit verbreitet, weshalb die Verwendung von NFE mit Code für das Internet insgesamt noch problematisch ist.)

Access Function Initializer (ES5 +)

Manchmal können Funktionen weitgehend unbemerkt durchdringen. was ist mit Zugriffsfunktionen. 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" 

Bitte beachten Sie, dass ich bei der Verwendung der Funktion () nicht verwendet habe! Dies liegt daran, dass es sich um eine Zugriffsfunktion für eine Eigenschaft handelt. Wir bekommen und setzen die Eigenschaft wie üblich, aber hinter den Kulissen wird eine Funktion aufgerufen.

Sie können Zugriffsfunktionen auch mit Object.defineProperty , Object.defineProperties und dem weniger bekannten zweiten Object.create Argument Object.create .

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, was n => n * 2 im Aufruf von map() verborgen ist. Dies ist eine Funktion.

Ein paar Dinge zu den Funktionen von Pfeilen:

  1. Das haben sie nicht. Sie schließen stattdessen this Kontext, in dem sie definiert sind. (Sie sind auch nahe an arguments und gegebenenfalls super .) Dies bedeutet, dass this in ihnen genauso ist, wo sie erstellt werden, und nicht geändert werden kann.

  2. Wie bereits erwähnt, verwenden Sie die function Schlüsselworts nicht. Verwenden Sie stattdessen => .

Beispiel n => n * 2 oben ist eine ihrer Formen. Wenn Sie mehrere Argumente haben, um eine 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 Datensatz als erstes Argument und den Index als zweites übergibt.)

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

Wenn Sie mehr als nur einen Ausdruck ausführen, verwenden Sie wie üblich {} und eine explizite 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)); 

Eine Version ohne {... } wird als Pfeilfunktion mit einem Ausdruckskörper oder einem kurzen Körper bezeichnet. (Außerdem: Kurze Funktion des Pfeils.) Die Funktion mit {... } , die den Körper definiert, ist die Funktion des Pfeils mit dem Körper der Funktion. (Auch: die Verbpfeilfunktion.)

Methodendeklaration im Objektinitialisierer (ES2015 +)

ES2015 ermöglicht eine kürzere Eigenschaftsdeklaration, die auf eine als Methodendefinition bezeichnete Funktion verweist. es sieht so aus:

 var o = { foo() { } }; 

fast gleich in ES5 und früheren Versionen:

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

Der Unterschied (mit Ausnahme der Ausführlichkeit) besteht darin, dass die Methode super kann, die Funktion jedoch nicht. Wenn Sie beispielsweise über ein Objekt valueOf , das valueOf Hilfe der Syntax einer Methode definiert, könnte es super.valueOf() , um den Wert von Object.prototype.valueOf der zurückgegeben werden muss (bevor etwas super.valueOf() etwas anderes dabei), während die ES5-Version stattdessen Object.prototype.valueOf.call(this) machen muss Object.prototype.valueOf.call(this) .

Dies bedeutet auch, dass die Methode einen Verweis auf das Objekt hat, für das sie definiert wurde. Wenn dieses Objekt temporär ist (wenn Sie es Object.assign als eines der ursprünglichen Objekte an Object.assign ), kann die Syntax der Methode bedeuten, dass das Objekt in gespeichert wird Speicher, wenn es sonst vom Garbage Collector erfasst werden könnte (wenn die JavaScript-Engine diese Situation nicht erkennt und nicht handhabt, wenn keine der Methoden super ).

Konstruktor- und Methodendeklarationen in der class (ES2015 +)

ES2015 liefert uns die class einschließlich der deklarierten Konstruktoren und Methoden:

 class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } getFullName() { return this.firstName + " " + this.lastName; } } 

Oben sind zwei Funktionsdeklarationen: eine für den Konstruktor mit dem Namen Person und getFullName für getFullName , eine Funktion, die Person.prototype zugewiesen Person.prototype .

574
04 марта '14 в 16:35 2014-03-04 16:35 Die Antwort wird von TJ Crowder am 04. März 14 um 16:35 Uhr 2014-03-04 16:35 gegeben

In Bezug auf den globalen Kontext erstellen die var- und die FunctionDeclaration Anweisung am Ende eine nicht löschbare Eigenschaft für das globale Objekt. Der Wert von beiden kann jedoch überschrieben werden.

Der subtile Unterschied zwischen den beiden Möglichkeiten besteht darin, dass beim Starten des Variablen-Instantiierungsprozesses (vor der eigentlichen Codeausführung) alle mit var deklarierten Bezeichner mit undefined initialisiert werden und die von FunctionDeclaration ab sofort verfügbar sind, zum Beispiel:

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

Die Zuweisung des FunctionExpression erfolgt vor der Ausführung.

Die von FunctionDeclaration erstellte globale Eigenschaft kann auf dieselbe Weise wie der Wert einer Variablen problemlos überschrieben werden. Beispiel:

  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 (z. B. beim Überprüfen des Aufrufstacks) sehr nützlich sein kann.

Zu Ihrem bearbeiteten ersten Beispiel ( foo = function() { alert('hello!'); }; ), Dies ist eine nicht deklarierte Aufgabe. Ich empfehle Ihnen dringend, immer das Schlüsselwort var .

Wird der Verweisbezeichner ohne var Operator nicht in der Gültigkeitsbereichskette gefunden, wird er zu einer entfernbaren Eigenschaft des globalen Objekts.

Darüber hinaus werfen nicht deklarierte Aufgaben einen ReferenceError auf ECMAScript 5 im strengen Modus .

Ein muss lesen:

Hinweis : Diese Antwort wurde aus einer anderen Frage kombiniert, in der der Hauptzweifel und die falsche Vorstellung von OP darin bestand, dass mit einer FunctionDeclaration deklarierte Bezeichner nicht überschrieben werden konnten. Dies ist jedoch nicht der Fall.

137
08 авг. die antwort wird von CMS 08 aug gegeben. 2010-08-08 22:32 '10 um 10:32 2010-08-08 22:32

Die beiden Code-Snippets, die Sie dort einfügen, werden sich für fast alle Zwecke gleich verhalten.

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

In der zweiten Variante ( function functionTwo() ) steht die Funktion für den Code zur Verfügung, der oben ausgeführt wird und in dem die Funktion deklariert ist.

Dies liegt daran, dass in der ersten Variante die Funktion zur Laufzeit der Variablen foo zugewiesen wird. In der zweiten Funktion wird diese Kennung während der Analyse foo zugewiesen.

Zusätzliche technische Informationen

JavaScript bietet drei Möglichkeiten, Funktionen zu definieren.

  • In Ihrem ersten Fragment wird der Funktionsausdruck angezeigt. Dies liegt an der Verwendung des Operators "function" zum Erstellen einer Funktion - das Ergebnis dieses Operators kann in einer beliebigen Variablen oder einem Objekt gespeichert werden. Der Funktionsausdruck ist so mächtig. Ein Funktionsausdruck wird häufig als "anonyme Funktion" bezeichnet, da er keinen Namen haben sollte.
  • Das zweite Beispiel ist eine Funktionsdeklaration. . Um eine Funktion zu erstellen, verwenden Sie den Operator "function". Die Funktion wird während der Analyse bereitgestellt und kann überall in diesem Bereich aufgerufen werden. Sie können es später in einer Variablen oder einem Objekt speichern.
  • Die dritte Möglichkeit, eine Funktion zu definieren, ist der Konstruktor "Function ()" , der in der ursprünglichen Nachricht nicht angezeigt wird. Es wird nicht empfohlen, dies zu verwenden, da es auf die gleiche Weise wie eval() funktioniert, das seine eigenen Probleme hat.
115
20 апр. die antwort wurde von thomasrutter am 20. april gegeben 2010-04-20 07:54 '10 am 7:54 2010-04-20 07:54

Greg antworte auf beste Erklärung

 functionTwo(); function functionTwo() { } 

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

Weil:

Funktionsdeklarationen und Variablendeklarationen werden mit dem JavaScript-Interpreter immer unsichtbar an den oberen Rand ihrer Region verschoben ( hoisted ). Natürlich gibt es bereits funktionale Parameter und Sprachnamen. Ben Cherry

Dies bedeutet, dass ein solcher Code:

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

Bitte beachten Sie, dass ein Teil der Deklaration von Erklärungen nicht erhoben wurde. Nur der Name wird erhoben.

Bei Funktionsdeklarationen wird jedoch auch der Körper der gesamten Funktion angehoben:

 functionTwo(); --------------- function functionTwo() { | is actually | }; function functionTwo() { | interpreted |--> } | like | functionTwo(); --------------- 
96
09 авг. die antwort wird mit simple_human 09 aug gegeben. 2014-08-09 05:45 '14 um 05:45 Uhr 2014-08-09 05:45 Uhr

Andere Kommentatoren haben bereits den semantischen Unterschied zwischen den beiden oben aufgeführten Optionen berücksichtigt. Ich möchte auf einen stilistischen Unterschied hinweisen: Nur eine Variation von "destination" kann die Eigenschaft eines anderen Objekts feststellen.

Ich erstelle häufig JavaScript-Module mit diesem Muster:

 (function(){ var exports = {}; function privateUtil() { ... } exports.publicUtil = function() { ... }; return exports; })(); 

Mit dieser Vorlage verwenden Ihre öffentlichen Funktionen das Ziel, während Ihre privaten Funktionen die Anzeige verwenden.

(Beachten Sie auch, dass die Zuweisung nach der Anweisung ein Semikolon enthalten muss, während die Ankündigung dies verbietet.)

87
03 марта '11 в 22:19 2011-03-03 22:19 antwortete Sean McMillan am 3. März 11 um 22:19 2011-03-03 22:19

Wenn Sie die erste Methode besser für die zweite Methode verwenden möchten, sollten Sie die Funktion der vorherigen Definitionen nicht überschreiben.

Mit

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

Diese Definition myfunction überschreibt alle vorherigen Definitionen, da sie während der Analyse ausgeführt wird.

Während

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

führt den richtigen Job aus, um myfunction nur zu definieren, wenn die condition ausgeführt wird.

73
29 марта '13 в 16:26 2013-03-29 16:26 Antwort von Mbengue Assane am 29. März 13 um 16:26 Uhr 2013-03-29 16:26

Ein wichtiger Grund ist das Hinzufügen einer und nur einer Variablen als "Wurzel" Ihres Namespaces ...

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

oder

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

Es gibt viele Methoden für den Namespace. Dies wird mit den vielen verfügbaren JavaScript-Modulen wichtiger.

Siehe auch Wie deklariert man den Namespace in Javascript?

59
08 авг. Die Antwort gibt Rob 08 Aug. 2010-08-08 22:44 '10 um 10:44 PM 2010-08-08 22:44

Hoisting ist eine JavaScript-Interpreteraktion, um alle Deklarationen von Variablen und Funktionen an den Anfang des aktuellen Bereichs zu verschieben.

Es werden jedoch nur tatsächliche Erklärungen ausgegeben. Aufträge hinterlassen, wo sie sind.

  • Eine innerhalb der Seite deklarierte Variable / Funktion ist überall auf dieser Seite verfügbar.
  • переменные/функции, объявленные внутри функции, имеют локальную область. означает, что они доступны/доступны внутри тела функции (scope), они недоступны вне тела функции.

Variable

Javascript называется свободно типизированным языком. Это означает, что переменные Javascript могут содержать значение любого Data-Type . Javascript автоматически позаботится об изменении типа переменной на основе значения/литерала, предоставленного во время выполнения.

 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. }; 

Функция

 function Identifier_opt ( FormalParameterList_opt ) { FunctionBody | sequence of statements « return; Default undefined « return 'some data'; } 
  • функции, объявленные внутри страницы, поднимаются на верх страницы, имеющей глобальный доступ.
  • функции, объявленные внутри функционального блока, поднимаются до вершины блока.
  • Возвращаемое значение по умолчанию функции: undefined ', Variable значение по умолчанию объявления также 'undefined'

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

Объявление функции

 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 

Выражение функции

  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' }; 

Функция, назначенная переменной Пример:

 (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 интерпретируется как

 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(); 

Вы можете проверить декларацию функции, тест выражения в другом браузере, используя jsperf Test Runner


Классы функций конструктора ES5 : Объекты функций, созданные с помощью Function.prototype.bind

JavaScript рассматривает функции как объекты первого класса, поэтому, будучи объектом, вы можете назначить свойства функции.

 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 представила функцию стрелки : выражение функции стрелки имеет более короткий синтаксис, они лучше всего подходят для функций не-метода, и они не могут использоваться как конструкторы.

ArrowFunction : ArrowParameters => ConciseBody .

 const fn = (item) => { return item  1 ? 'Odd' : 'Even'; }; console.log( fn(2) ); // Even console.log( fn(3) ); // Odd 
52
ответ дан Yash 25 янв. '16 в 17:46 2016-01-25 17:46

Я добавляю свой собственный ответ только потому, что все остальные полностью закрыли подъемную часть.

Я задавался вопросом, какой путь лучше уже давно, и благодаря http://jsperf.com теперь я знаю:)

2019

36
ответ дан Leon Gaban 01 мая '15 в 18:06 2015-05-01 18:06

Объявление функции и выражение функции, назначенное переменной, ведут себя одинаково после установления привязки.

Однако существует разница в том, как и когда объект функции фактически связан с его переменной. Это различие связано с механизмом, называемым переменным подъемом в JavaScript.

В принципе, все объявления функций и объявления переменных поднимаются в начало функции, в которой происходит объявление (поэтому мы говорим, что JavaScript имеет область видимости).

  • Когда объявляется объявление функции, тело функции "следует" поэтому, когда тело функции оценивается, переменная немедленно быть привязанным к объекту функции.

  • Когда объявление переменной отображается, инициализация не следовать, но "оставлен". Переменная инициализируется undefined в начале тела функции и будет назначен значение в исходном месте в коде. (На самом деле ему присваивается значение в каждом месте, где происходит объявление переменной с тем же именем.)

Порядок подъема также важен: объявления функций имеют приоритет над объявлениями переменных с тем же именем, а последнее объявление функции имеет приоритет над предыдущими объявлениями с тем же именем.

Некоторые примеры...

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

Переменная foo поднимается в начало функции, инициализируется до undefined , так что !foo равно true , поэтому foo присваивается 10 . foo вне области bar не играет никакой роли и нетронутой.

 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 

Объявления функций имеют приоритет над объявлениями переменных, а последнее объявление функции "прилипает".

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

В этом примере a инициализируется объектом функции, полученным в результате оценки объявления второй функции, а затем назначается 4 .

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

Здесь объявляется объявление функции, объявление и инициализация переменной a . Затем этой переменной присваивается 10 . Другими словами: присваивание не присваивается внешней переменной a .

32
ответ дан eljenso 06 февр. '13 в 19:29 2013-02-06 19:29

Первый пример - объявление функции:

 function abc(){} 

Второй пример - это выражение функции:

 var abc = function() {}; 

Основное различие заключается в том, как они поднимаются (поднимаются и объявляются). В первом примере объявляется объявление всей функции. Во втором примере поднимается только var 'abc', его значение (функция) будет undefined, а сама функция остается в том положении, в котором она объявлена.

Проще говоря:

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

Чтобы узнать больше об этой теме, я настоятельно рекомендую вам это ссылка

30
ответ дан sla55er 05 июня '14 в 11:28 2014-06-05 11:28

С точки зрения стоимости обслуживания кода более предпочтительными являются названные функции:

  • Независимо от места, где они объявлены (но все же ограничены областью).
  • Более устойчив к ошибкам, таким как условная инициализация (вы все еще можете переопределить, если захотите).
  • Код становится более читаемым, выделяя локальные функции отдельно от функциональности области. Обычно в область действия сначала входят функции, а затем декларации локальных функций.
  • В отладчике вы явно увидите имя функции в стеке вызовов вместо функции "анонимный/оцененный".

Я подозреваю, что больше PROS для названных функций. И то, что указано как преимущество названных функций, является недостатком для анонимных.

Исторически анонимные функции появились из-за невозможности JavaScript как языка для перечисления членов с именованными функциями:

 { member:function() {  } } 
28
ответ дан Sasha Firsov 23 янв. '10 в 23:32 2010-01-23 23:32

Я использую переменный подход в своем коде по очень определенной причине, теория которого была рассмотрена абстрактным образом выше, но пример может помочь некоторым людям, как я, с ограниченным опытом JavaScript.

У меня есть код, который мне нужно запустить с 160 независимо разработанными брендингами. Большая часть кода находится в общих файлах, но специфичные для брендинга вещи находятся в отдельном файле, по одному для каждого бренда.

Некоторые брендинги требуют определенных функций, а некоторые нет. Иногда мне приходится добавлять новые функции для создания новых брендинговых вещей. Я рад изменить общий код, но я не хочу менять все 160 наборов файлов брендинга.

Используя синтаксис переменных, я могу объявить переменную (по существу, указатель функции) в общем коде и либо назначить тривиальную функцию заглушки, либо установить значение null.

Один или два брендинга, которые нуждаются в конкретной реализации функции, могут затем определить свою версию функции и назначить ее переменной, если они этого захотят, а остальные ничего не делают. Я могу проверить нулевую функцию, прежде чем выполнять ее в общем коде.

Из комментариев пользователей выше, я понимаю, что может быть и переопределить статическую функцию, но я думаю, что решение переменной хорошо и понятно.

24
ответ дан Herc 29 нояб. '12 в 14:28 2012-11-29 14:28

В терминах компьютерной науки мы говорим об анонимных функциях и названных функциях. Я думаю, что самое важное отличие состоит в том, что анонимная функция не связана с именем, отсюда и анонимная функция. В JavaScript это объект первого класса, динамически объявленный во время выполнения.

Для получения дополнительной информации об анонимных функциях и исчислении лямбда, Википедия - хорошее начало ( http://en.wikipedia.org/wiki/Anonymous_function ).

22
ответ дан Kafka 18 дек. '08 в 22:30 2008-12-18 22:30

Greg Answer достаточно хорош, но я все еще хотел бы добавить что-то к нему, что я узнал только сейчас, наблюдая видео Дугласа Крокфорда.

Функциональное выражение:

 var foo = function foo() {}; 

Оператор функции:

 function foo() {}; 

Оператор функции является просто сокращением для оператора var с function значением.

Итак,

 function foo() {}; 

расширяется до

 var foo = function foo() {}; 

Расширяется далее:

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

И они оба подняты в верхней части кода.

2019

22
ответ дан Rohan 21 июля '15 в 10:45 2015-07-21 10:45

@EugeneLazutkin дает пример, где он называет назначенную функцию, чтобы иметь возможность использовать shortcut() как внутренняя ссылка на себя. John Resig дает еще один пример - копирование рекурсивной функции, назначенной другому объекту в Изучение расширенного Javascript . Хотя назначение функций свойствам здесь не является строго вопросом, я рекомендую активно пробовать учебник - запустите код, нажав кнопку в правом верхнем углу, и дважды щелкните по коду, чтобы изменить его по своему вкусу.

Примеры из учебника: рекурсивные вызовы в yell() :

Тесты выходят из строя, когда исходный объект ниндзя удален. (стр. 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?" ); } 

Если вы назовете функцию, которая будет вызываться рекурсивно, тесты пройдут. (стр. 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 04 авг. '12 в 18:24 2012-08-04 18:24

Другое отличие, которое не упоминается в других ответах, заключается в том, что если вы используете анонимную функцию

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

и использовать это как конструктор, как в

 var one = new functionOne(); 

то one.constructor.name не будет определено. Function.name является нестандартным, но поддерживается браузерами Firefox, Chrome, других Webkit и IE 9 +.

Mit

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

можно получить имя конструктора в виде строки с two.constructor.name .

15
ответ дан Ingo Kegel 15 окт. '12 в 13:42 2012-10-15 13:42

Если вы будете использовать эти функции для создания объектов, вы получите:

 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 25 окт. '13 в 19:38 2013-10-25 19:38

Я перечисляю следующие различия:

  • Объявление функции может быть размещено в любом месте кода. Даже если он вызывается до того, как определение появляется в коде, оно запускается, поскольку объявление функции передается в память или таким образом, что оно поднимается вверх, прежде чем какой-либо другой код на странице начнет выполнение.

    Взгляните на приведенную ниже функцию:

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

    Это происходит потому, что во время выполнения оно выглядит так: -

     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 

    Выражение функции, если оно не определено до его вызова, приведет к ошибке. Кроме того, здесь само определение функции не перемещается в верхнюю часть или не помещается в память, как в объявлениях функций. Но переменная, которой мы назначаем функцию, поднимается вверх, и ей присваивается undefined .

    Те же функции, что и функциональные выражения:

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

    Это происходит потому, что во время выполнения он выглядит так:

     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 
  • Нельзя записывать объявления функций в не-функциональных блоках, например , если , потому что они не будут доступны.

     if (test) { function x() { doSomething(); } } 
  • Именованное выражение функции, подобное приведенному ниже, может не работать в браузерах Internet Explorer до версии 9.

     var today = function today() {return new Date()} 
14
ответ дан varna 09 сент. '15 в 13:30 2015-09-09 13:30

Первый (функция doSomething (x)) должен быть частью нотации объекта.

Второй ( var doSomething = function(x){ alert(x);} ) просто создает анонимную функцию и присваивает ее переменной doSomething . Таким образом doSomething() вызовет функцию.

Возможно, вам захочется узнать, что такое объявление функции и выражение функции.

Объявление функции определяет именованную функциональную переменную без необходимости назначения переменной. Объявления функций встречаются как автономные конструкции и не могут быть вложены в не функциональные блоки.

 function foo() { return 3; } 

ECMA 5 (13.0) определяет синтаксис как
Идентификатор функции (FormalParameterList opt ) {FunctionBody}

В приведенном выше состоянии имя функции видимо в пределах ее области действия и области ее родителя (иначе это было бы недостижимо).

И в выражении функции

Функциональное выражение определяет функцию как часть синтаксиса большего выражения (обычно назначение переменной). Функции, определенные выражениями функций, можно назвать или анонимными. Выражения функций не должны начинаться с "функции".

 // 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) определяет синтаксис как
Идентификатор функции opt (FormalParameterList opt ) {FunctionBody}

14
ответ дан NullPoiиteя 05 янв. '13 в 21:37 2013-01-05 21:37

В свете аргументов "названные функции отображаются в стеках" современные механизмы JavaScript на самом деле вполне способны представлять анонимные функции.

Начиная с этой записи, V8, SpiderMonkey, Chakra и Nitro всегда ссылаются на именованные функции по их именам. Они почти всегда ссылаются на анонимную функцию по ее идентификатору, если она есть.

SpiderMonkey может определить имя анонимной функции, возвращенной из другой функции. Остальное не может.

Если вы действительно хотите, чтобы ваш итератор и успешные обратные вызовы отображались в трассировке, вы могли бы назвать их тоже...

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

Но по большей части это не стоит подчеркивать.

Жгут проводов ( 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 ei (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 

SpiderMonkey

 func.name: Trace: a@http://localhost:8000/test.js:4:5 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: b Trace: b@http://localhost:8000/test.js:7:9 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: d Trace: d@http://localhost:8000/test.js:10:9 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: Trace: a@http://localhost:8000/test.js:4:5 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: b Trace: b@http://localhost:8000/test.js:7:9 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: d Trace: d@http://localhost:8000/test.js:10:9 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: Trace: ei@http://localhost:8000/test.js:17:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: j Trace: j@http://localhost:8000/test.js:20:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: l Trace: l@http://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: n@http://localhost:8000/test.js:33:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: p Trace: p@http://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 ei (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) 

Нитро

 func.name: Trace: a@http://localhost:8000/test.js:4:22 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: b Trace: b@http://localhost:8000/test.js:7:26 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: d Trace: d@http://localhost:8000/test.js:10:26 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: Trace: a@http://localhost:8000/test.js:4:22 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: b Trace: b@http://localhost:8000/test.js:7:26 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: d Trace: d@http://localhost:8000/test.js:10:26 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: Trace: i@http://localhost:8000/test.js:17:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: j Trace: j@http://localhost:8000/test.js:20:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: l Trace: l@http://localhost:8000/test.js:23:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: Trace: http://localhost:8000/test.js:28:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: n Trace: n@http://localhost:8000/test.js:33:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: p Trace: p@http://localhost:8000/test.js:38:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 
12
ответ дан Jackson 12 окт. '14 в 3:58 2014-10-12 03:58

Существует четыре заслуживающих внимания сравнения между двумя различными объявлениями функций, перечисленными ниже.

  1. Наличие (объем) функции

Следующее работает, потому что function add() находится в пределах ближайшего блока:

 try { console.log("Success: ", add(1, 1)); } catch(e) { console.log("ERROR: " + e); } var add=function add(a, b){ return a + b; } 

Следующее не работает, потому что add объявлен после того, как он используется.

 function foobar(a, b){} console.log(foobar.name); 

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

Если для функции не заданы переменные, то именем функции является пустая строка ( "" ).

 var a = function(){}; var b = a; var c = b; console.log(a.name); console.log(b.name); console.log(c.name); 
  1. Leistung

В Google V8 и Firefox Spidermonkey может быть разница в несколько микросекундных JIST-компиляций, но в итоге результат будет точно таким же. Чтобы доказать это, давайте рассмотрим эффективность JSPerf в микробенчмарках, сравнив скорость двух пустых фрагментов кода. Тесты JSPerf находятся здесь . И тесты jsben.ch находятся здесь . Как видите, есть заметная разница, когда их не должно быть. Если вы действительно такой же фанат производительности, как я, то, возможно, вам стоит попытаться уменьшить количество переменных и функций в области и, в частности, устранить полиморфизм (например, использовать одну и ту же переменную для хранения двух разных типов).

  1. Изменчивость изменчивости

Когда вы используете ключевое слово var для объявления переменной, вы можете переназначить другое значение этой переменной следующим образом.

 (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); })(); 

Интересно, что если мы объявим переменную как function funcName(){} , то неизменность переменной будет такой же, как и объявление ее с помощью var .

 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} 
  • Нормальная function add(){}

  • Оператор (например, if , else , for while , try / catch / finally , switch , do / while , with )

  • Функция стрелки с function add()

ответ дан Jack Giffin 15 янв. '18 в 4:55 2018-01-15 04:55

В JavaScript существует два способа создания функций:

  • Объявление функции:

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

    Это очень простой и понятный язык, используемый на многих языках и стандартом для семейств языков C. Мы объявили функцию, определенную ею, и выполнили ее, вызвав ее.

    Что вы должны знать, так это то, что функции на самом деле являются объектами в JavaScript; внутри мы создали объект для функции выше и дали ему имя, называемое fn, или ссылка на объект хранится в fn. Функции - объекты в JavaScript; экземпляр функции на самом деле является экземпляром объекта.

  • Функциональное выражение:

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

    JavaScript имеет первоклассные функции, т.е. создает функцию и назначает ее переменной так же, как вы создаете строку или номер и присваиваете ее переменной. Здесь переменной fn присваивается функция. Причиной этого понятия являются функции - объекты в JavaScript; fn указывает на экземпляр объекта указанной выше функции. Мы инициализировали функцию и назначили ее переменной. Он не выполняет функцию и не назначает результат.

Ссылка: Синтаксис объявления функции JavaScript: var fn = function() {} vs function fn() {}

10
ответ дан Anoop Rai 14 авг. '16 в 12:13 2016-08-14 12:13

Оба являются разными способами определения функции. Разница заключается в том, как браузер интерпретирует и загружает их в контекст выполнения.

Первый случай - выражение функции, которое загружается только тогда, когда интерпретатор достигает этой строки кода. Поэтому, если вы сделаете это следующим образом, вы получите сообщение об ошибке, что functionOne не является функцией .

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

Причина в том, что в первой строке значение функции не назначено, и, следовательно, это undefined. Мы пытаемся назвать его функцией, и, следовательно, получаем ошибку.

Во второй строке мы назначаем функцию анонимной функции functionOne.

Второй случай - объявления функций, которые загружаются до выполнения любого кода. Поэтому, если вы делаете следующее, вы не получите никакой ошибки, поскольку объявление загружается до выполнения кода.

 functionOne(); function functionOne() { // Some code } 
8
ответ дан Nitin9791 28 дек. '16 в 23:18 2015-12-28 23:18

О производительности:

Новые версии V8 ввели несколько оптимизаций под капотом, а также SpiderMonkey .

Теперь между выражением и объявлением нет никакой разницы. Выражение функции теперь будет быстрее .

Chrome 62.0.3202 2019

ответ дан Panos Kal. 28 сент. '17 в 7:34 2017-09-28 07:34

Они довольно похожи с некоторыми небольшими отличиями, первая - это переменная, которая назначается анонимной функции (Объявление функции), а вторая - обычным способом создания функции в JavaScript (анонимная декларация функции), у обоих есть использование, минусы и профи:

1. Выражение функции

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

Функция Expression определяет функцию как часть большего синтаксис выражений (обычно назначение переменной). функции определенные через функции Выражения могут быть названы или анонимными. функция Выражения не должны начинаться с "функции" (следовательно, круглые скобки вокруг примера самопривязывания ниже).

Назначить переменную функции, значит нет Подъем, так как мы знаем, что функции в JavaScript могут Hoist, означает, что они могут быть вызваны до того, как они будут объявлены, в то время как переменные должны быть объявлены до получения доступа к ним, поэтому в этом случае мы не можем получить доступ к функции до того, где она была заявлена, и это может быть способ, которым вы пишете свои функции, для функций, возвращающих другую функцию, такая декларация может иметь смысл, также в ECMA6 и выше вы можете назначить это arrow, которая может использоваться для вызова анонимных функций, также этот способ объявления - лучший способ создания функций конструктора в JavaScript.

2. Объявление функции

 function functionTwo() { // Some code } 

Объявление функции определяет именованную функциональную переменную без требующих назначения переменных. Объявление функций происходит как автономные конструкции и не могут быть вложены в не-функциональные блоки. Полезно думать о них как о братьях и сестрах переменных объявлений. Подобно тому, как объявления переменных должны начинаться с "var", Function Объявления должны начинаться с "функции".

Это обычный способ вызова функции в JavaScript, эта функция может быть вызвана до того, как вы ее объявите, как и в JavaScript. Все функции Get Hoisted, но если вы используете "strict", это не будет поднять, как ожидалось, это хороший способ вызвать все нормальные функции, которые не являются большими в строках, и ни одна из них не является конструкторской функцией.

Кроме того, если вам нужна дополнительная информация о том, как работает подъем в JavaScript, перейдите по ссылке ниже:

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

7
ответ дан Alireza 09 мая '17 в 16:56 2017-05-09 16:56

Это всего лишь два возможных способа объявления функций, а во втором - использование функции перед объявлением.

5
ответ дан Tao 24 июня '15 в 13:08 2015-06-24 13:08

new Function() может использоваться для передачи тела функции в строку. И, следовательно, это можно использовать для создания динамических функций. Также передайте script без выполнения script.

 var func = new Function("x", "y", "return x*y;"); function secondFunction(){ var result; result = func(10,20); console.log ( result ); } secondFunction() 
4
ответ дан SuperNova 10 мая '16 в 10:05 2016-05-10 10:05
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос