Was ist das Konstrukt (function () {}) () in JavaScript?


790

Früher wusste ich, was das bedeutet, aber jetzt kämpfe ich ...

Sagt das im Grunde document.onload?

(function () {

})();

20
Übrigens, obwohl Sie Leute sehen werden, die diese Funktion "selbstaufrufend" nennen, ist das eindeutig nicht wahr. Der Begriff Leben hat den Vorteil der Genauigkeit.
AakashM

6
Dies gibt eine gute Erklärung für dieses Konstrukt. Hier entstand auch der Begriff "IIFE". benalman.com/news/2010/11/…
jeremysawesome


2
Die Benennung dieses Konstrukts finden Sie auch hier . Lesen Sie mehr über den Zweck dieses Konstrukts und eine technische Erklärung (auch hier ). Schauen Sie sich für die Syntax an, warum die Klammern notwendig sind und wohin sie gehen sollen .
Bergi

Antworten:


854

Es ist ein sofort aufgerufener Funktionsausdruck , kurz IIFE . Es wird sofort ausgeführt, nachdem es erstellt wurde.

Es hat nichts mit einem Event-Handler für Events (wie document.onload) zu tun .
Betrachten Sie den Teil im ersten Klammerpaar: .... es ist ein regulärer Funktionsausdruck. Schauen Sie sich dann das letzte Paar an . Dieses wird normalerweise einem Ausdruck hinzugefügt, um eine Funktion aufzurufen. in diesem Fall unser vorheriger Ausdruck.(function(){})();(function(){})();

Dieses Muster wird häufig verwendet, um eine Verschmutzung des globalen Namespace zu vermeiden, da alle im IIFE verwendeten Variablen (wie bei jeder anderen normalen Funktion) außerhalb des Gültigkeitsbereichs nicht sichtbar sind.
Aus diesem Grund haben Sie diese Konstruktion möglicherweise mit einem Event-Handler verwechselt window.onload, weil sie häufig wie folgt verwendet wird:

(function(){
  // all your code here
  var foo = function() {};
  window.onload = foo;
  // ...
})();
// foo is unreachable here (it’s undefined)

Von Guffa vorgeschlagene Korrektur :

Die Funktion wird direkt nach ihrer Erstellung ausgeführt, nicht nachdem sie analysiert wurde. Der gesamte Skriptblock wird analysiert, bevor der darin enthaltene Code ausgeführt wird. Parsing-Code bedeutet auch nicht automatisch, dass er ausgeführt wird. Wenn sich beispielsweise das IIFE in einer Funktion befindet, wird es erst ausgeführt, wenn die Funktion aufgerufen wird.

Update Da dies ein ziemlich beliebtes Thema, es ist erwähnenswert , dass IIFE der kann auch mit geschrieben werden ES6 des Pfeil - Funktion (wie Gajus hat darauf hingewiesen , in einem Kommentar ):

((foo) => {
 // do something with foo here foo
})('foo value')

@ gion_13 Was ist der Unterschied zwischen der Erstellungsphase und der Analysephase?
Akantoword

1
@jlei so wie ich es sehe, umfasst der Lebenszyklus eines js-Programms die folgenden Phasen: Parsen, Erstellen / Kompilieren, Ausführen. Obwohl die tatsächliche Implementierung (und Benennung :)) von Browser zu Browser unterschiedlich sein kann, können wir diese Phasen in unserem Code bestimmen, indem wir auf Analysefehler, Hebe- und Laufzeitfehler achten. Ich persönlich habe hier nicht viele Ressourcen gefunden, weil es zu niedrig ist und nicht vom Programmierer gesteuert werden kann. Sie können eine Art Erklärung in diesem SO-Beitrag finden: stackoverflow.com/a/34562772/491075
gion_13

@sam firat von allen gibt es die varianle-Deklaration und das neue Schlüsselwort. Dies bedeutet, dass Sie in Ihrem Beispiel ein neues Objekt instanziieren, das durch seinen Konstruktor (anonymer Funktionsausdruck) definiert ist, und es über den neuen Operator aufgerufen wird, nicht durch Aufrufen der Funktion wie im IIFE-Beispiel. Sicher, diese Funktion wirkt wie ein Abschluss für ihren Inhalt, aber es ist bei weitem ein anderer Anwendungsfall.
gion_13

Wie verschmutzt dies den globalen Namespace? foo ist außerhalb der Funktion sowieso nicht verfügbar. function(){ var foo = '5'; }
Pankaj

1
@Pankaj - Für sich genommen ist das nicht einmal syntaktisch gültiges JS (es ist ein Funktionsausdruck, aber nicht im Ausdruckskontext und wird daher als Syntaxfehler behandelt).
Quentin

109

Es ist nur eine anonyme Funktion, die direkt nach ihrer Erstellung ausgeführt wird.

Es ist so, als hätten Sie es einer Variablen zugewiesen und direkt danach verwendet, nur ohne die Variable:

var f = function () {
};
f();

In jQuery gibt es ein ähnliches Konstrukt, an das Sie vielleicht denken:

$(function(){
});

Das ist die Kurzform der Bindung des readyEreignisses:

$(document).ready(function(){
});

Die obigen zwei Konstrukte sind jedoch keine IIFE .


83
Die letzten beiden sind nicht wirklich IIFEs, da sie aufgerufen werden, wenn das DOM fertig ist und nicht sofort
svvac

15
@swordofpain: Ja, das ist richtig, sie sind keine IIFEs.
Guffa

@swordofpain unter Berücksichtigung des zweiten Snippets; Würde add () am Ende der Funktion einen Wert haben, wenn sie in ein IIFE umgewandelt wird?
Zeitbandit

Ist das Semikolon am Ende notwendig?
FrenkyB

@FrenkyB Nicht erforderlich, nein, aber empfohlen (Semikolons sind in Javascript häufig nicht erforderlich, aber es ist eine gute Praxis). Jede dieser Anweisungen enthält anonyme Funktionen und keine Funktionsdeklarationen.
Ledivin

52

Ein sofort aufgerufener Funktionsausdruck (IIFE) ruft sofort eine Funktion auf. Dies bedeutet einfach, dass die Funktion unmittelbar nach Abschluss der Definition ausgeführt wird.

Drei weitere gebräuchliche Formulierungen:

// Crockford's preference - parens on the inside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
}());

//The OPs example, parentheses on the outside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
})();

//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
  console.log('Welcome to the Internet. Please follow me.');
}();

Wenn es keine besonderen Anforderungen für den Rückgabewert gibt, können wir schreiben:

!function(){}();  // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}();  // => NaN

Alternativ kann es sein:

~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();

Sie können sogar schreiben:

new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required

4
letzte 31.new'ist ungültige Syntax
Katze

9
Warum gibt es so viele Möglichkeiten, dasselbe zu schreiben? !! > _ <Ich mag diese Sprache nicht
Awesome_girl

6
aaund der Gewinner ist;(function(){}());
Roko C. Buljan

Die Crockford Präferenz Erklärung war sehr nützlich - erklärt die Unterschiede , die ich in der freien Natur gesehen haben, zum Beispiel die jQuery tiny-PubSub Kern wechselte von einer Version zur anderen (Sie die Änderung am Ende der Datei sehen kann) und ich couldn‘ Ich finde nicht heraus warum.
icc97

1
@Awesome_girl: Es gibt nicht viele Möglichkeiten, dasselbe zu schreiben. Es ist so, dass JS ein loses Typsystem mit Operatoren hat, die mit jedem Werttyp arbeiten können. Sie können 1 - 1und Sie können genauso einfach tun true - function(){}. Es ist nur eine Sache (ein Infix-Subtraktionsoperator), aber mit unterschiedlichen, sogar unsinnigen Operanden.

31

Es deklariert eine anonyme Funktion und ruft sie dann auf:

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);

Ich denke, "Argumente" sind äußere Variablen, die als "arg" bezeichnet werden und im lokalen Kontext innerhalb der Funktion verwendet werden sollen.
Dalibor

@ Dalibor argumentsist etwas Besonderes ; Ich vermute, der Antwortende hat gerade umgedreht, wohin die Namen gehen
Katze

29

Das heißt sofort ausführen.

Also, wenn ich das tue:

var val = (function(){
     var a = 0;  // in the scope of this function
     return function(x){
         a += x;
         return a;
     };
})();

alert(val(10)); //10
alert(val(11)); //21

Geige: http://jsfiddle.net/maniator/LqvpQ/


Zweites Beispiel:

var val = (function(){
     return 13 + 5;
})();

alert(val); //18

1
Ich verstehe es nicht, was beweist das, dass es sich selbst anruft?
Exitos

1
@Exitos, weil es diese Funktion zurückgibt. Ich gebe ein zweites Beispiel.
Naftali aka Neal

sehr leicht zu verstehen +1
Adiii

24

Dieses Konstrukt wird als sofort aufgerufener Funktionsausdruck (IIFE) bezeichnet, was bedeutet, dass es sofort ausgeführt wird. Stellen Sie sich das als eine Funktion vor, die automatisch aufgerufen wird, wenn der Interpreter diese Funktion erreicht.

Häufigster Anwendungsfall:

Einer der häufigsten Anwendungsfälle besteht darin, den Umfang einer über erstellten Variablen zu begrenzen var. Variablen erstellt übervar haben einen auf eine Funktion beschränkten Bereich, sodass dieses Konstrukt (das ein Funktionsumbruch um bestimmten Code ist) sicherstellt, dass Ihr Variablenbereich nicht aus dieser Funktion herausläuft.

Im folgenden Beispiel ist countaußerhalb der sofort aufgerufenen Funktion nicht verfügbar, dh der Umfang von countwird nicht aus der Funktion austreten. Sie sollten eine bekommen ReferenceError, sollten Sie trotzdem versuchen, außerhalb der sofort aufgerufenen Funktion darauf zuzugreifen.

(function () { 
    var count = 10;
})();
console.log(count);  // Reference Error: count is not defined

ES6 Alternative (empfohlen)

In ES6 können jetzt Variablen über letund erstellt werden const. Beide haben einen Blockbereich (im Gegensatz zu einem varFunktionsbereich).

Anstatt dieses komplexe Konstrukt von IIFE für den oben erwähnten Anwendungsfall zu verwenden, können Sie jetzt viel einfacheren Code schreiben, um sicherzustellen, dass der Gültigkeitsbereich einer Variablen nicht aus Ihrem gewünschten Block herausläuft.

{ 
    let count = 10;
}
console.log(count);  // ReferenceError: count is not defined

In diesem Beispiel haben wir leteine countVariable definiert , die sich countauf den Codeblock beschränkt, den wir mit den geschweiften Klammern erstellt haben {...}.

Ich nenne es ein "Curly Jail".


10
Ich mag die Benennung des Curly Jail . Vielleicht bleibt es :)
gion_13

15
(function () {
})();

Dies wird als IIFE (Sofort aufgerufener Funktionsausdruck) bezeichnet. Als eines der bekanntesten JavaScript-Designmuster ist es das Herz und die Seele des modernen Modulmusters. Wie der Name schon sagt, wird es sofort ausgeführt, nachdem es erstellt wurde. Dieses Muster erstellt einen isolierten oder privaten Ausführungsbereich.

JavaScript vor ECMAScript 6 verwendete lexikalisches Scoping, daher wurde IIFE zur Simulation des Block-Scoping verwendet. (Mit ECMAScript 6 ist das Block-Scoping mit der Einführung der Schlüsselwörter letund möglich const.) Referenz für Probleme mit dem lexikalischen Scoping

Simulieren Sie das Block-Scoping mit IIFE

Der Leistungsvorteil IIFE ist die Verwendung ist die Möglichkeit , häufig verwendete globale Objekte zu übergeben , wie window, documentetc. als Argument durch den Umfang Nachschlag zu reduzieren. (Denken Sie daran, dass JavaScript nach Eigenschaften im lokalen Bereich sucht und die Kette bis zum globalen Bereich hochfährt.) Der Zugriff auf globale Objekte im lokalen Bereich reduziert die Suchzeit wie unten beschrieben.

(function (globalObj) {
//Access the globalObj
})(window);

Vielen Dank, dass Sie das Wesentliche zum Verständnis der zweiten Klammer in IIFE angegeben haben. Auch zur Verdeutlichung des Nachschlagezeitvorteils der globalen Variablen durch Definition in der Definition
Arsal

11

Nein, dieses Konstrukt erstellt nur einen Bereich für die Benennung. Wenn Sie es in Teile zerbrechen, können Sie sehen, dass Sie eine externe haben

(...)();

Das ist ein Funktionsaufruf. In der Klammer haben Sie:

function() {}

Das ist eine anonyme Funktion. Alles, was innerhalb des Konstrukts mit var deklariert wird, ist nur innerhalb desselben Konstrukts sichtbar und verschmutzt den globalen Namespace nicht.


11

Dies ist ein sofort aufgerufener Funktionsausdruck in Javascript:

Um IIFE in JS zu verstehen, lassen Sie es uns zusammenfassen:

  1. Ausdruck : Etwas, das einen Wert zurückgibt
    Beispiel: Probieren Sie Folgendes in der Chrome-Konsole aus. Dies sind Ausdrücke in JS.
a = 10 
output = 10 
(1+3) 
output = 4
  1. Funktionsausdruck :
    Beispiel:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');

Funktionsweise des Funktionsausdrucks:
- Wenn die JS-Engine zum ersten Mal ausgeführt wird (Ausführungskontext - Erstellungsphase), wird diese Funktion (rechts von = oben) nicht ausgeführt oder im Speicher gespeichert. Der Variablen 'greet' wird von der JS-Engine der Wert 'undefined' zugewiesen.
- Während der Ausführung (Ausführungskontext - Ausführungsphase) wird das Funktionsobjekt im laufenden Betrieb erstellt (es wird noch nicht ausgeführt ), der Variablen 'greet' zugewiesen und kann mit 'greet (' somename ')' aufgerufen werden.

3. Sofort aufgerufener Funktionsausdruck:

Beispiel:

// IIFE
var greeting = function(name) {
    return 'Namaste' + ' ' + name;
}('Santosh')

console.log(greeting)  // Namaste Santosh. 

So funktioniert IIFE :
- Beachten Sie das '()' unmittelbar nach der Funktionsdeklaration. Jedem Funktionsobjekt ist eine 'CODE'-Eigenschaft zugeordnet, die aufgerufen werden kann. Und wir können es mit '()' Klammern aufrufen (oder aufrufen).
- Hier wird also während der Ausführung (Ausführungskontext - Ausführungsphase) das Funktionsobjekt erstellt und gleichzeitig ausgeführt - Jetzt hat die Begrüßungsvariable anstelle des Funktionsobjekts ihren Rückgabewert (eine Zeichenfolge).

Typischer Anwendungsfall von IIFE in JS:

Das folgende IIFE-Muster wird ziemlich häufig verwendet.

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • Wir machen hier zwei Dinge. a) Umschließen unseres Funktionsausdrucks in geschweifte Klammern (). Dies teilt dem Syntaxparser mit, dass alles, was in () steht, ein Ausdruck (in diesem Fall ein Funktionsausdruck) und ein gültiger Code ist.
    b) Wir rufen diese Funktion gleichzeitig mit () am Ende auf.

Diese Funktion wird also gleichzeitig erstellt und ausgeführt (IIFE).

Wichtiger Anwendungsfall für IIFE:

IIFE schützt unseren Code.
- Als Funktion hat IIFE einen eigenen Ausführungskontext, dh alle darin erstellten Variablen sind lokal für diese Funktion und werden nicht mit dem globalen Ausführungskontext geteilt.

Angenommen, ich habe eine andere JS-Datei (test1.js), die in meiner Anwendung zusammen mit iife.js verwendet wird (siehe unten).

// test1.js

var greeting = 'Hello';

// iife.js
// Spelling of Function was not correct , result into error
(function (name) { 
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');

console.log(greeting)   // No collision happens here. It prints 'Hello'.

IIFE hilft uns also dabei , sicheren Code schreiben, bei dem wir nicht unbeabsichtigt mit den globalen Objekten kollidieren.


Wenn wir Funktionen in IIFE erstellen, wie können wir auf sie in einer anderen js- oder jsx-Datei zugreifen, dh in einer Reaktionskomponente.
Stone Rock

Obwohl wir IIFE nicht verwendet haben, kollidiert die Begrüßungsvariable nicht mit der globalen Begrüßungsvariablen. Was ist dort der Vorteil?
Willy David Jr

6

Das ist eine selbstaufrufende anonyme Funktion .

Lesen Sie die W3Schools-Erklärung einer selbstaufrufenden Funktion .

Funktionsausdrücke können "selbstaufrufend" gemacht werden.

Ein selbst aufrufender Ausdruck wird automatisch aufgerufen (gestartet), ohne aufgerufen zu werden.

Funktionsausdrücke werden automatisch ausgeführt, wenn auf den Ausdruck () folgt.

Sie können eine Funktionsdeklaration nicht selbst aufrufen.


3
(function named(){console.log("Hello");}());<- selbstausführende benannte Funktion
Bryc

@bryc warum würdest du eine Funktion benennen, die keinen Namen braucht?
RicardoGonzales

2
@ RicardoGonzales Rekursion Ich denke
Bryc

5

Dies ist die selbst aufrufende anonyme Funktion. Es wird ausgeführt, während es definiert ist. Dies bedeutet, dass diese Funktion definiert ist und sich unmittelbar nach der Definition aufruft.

Und die Erklärung der Syntax lautet: Die Funktion in der ersten ()Klammer ist die Funktion, die keinen Namen hat, und in der nächsten ();Klammer können Sie verstehen, dass sie zum Zeitpunkt der Definition aufgerufen wird. Und Sie können jedes Argument in dieser zweiten ()Klammer übergeben, das in der Funktion in der ersten Klammer erfasst wird. Siehe dieses Beispiel:

(function(obj){
    // Do something with this obj
})(object);

Hier ist das 'Objekt', das Sie übergeben, innerhalb der Funktion durch 'obj' zugänglich, da Sie es in der Funktionssignatur erfassen.


2
Diese Frage hat bereits eine akzeptierte Antwort und Ihre Antwort fügt nichts hinzu, was noch nicht von der akzeptierten Antwort abgedeckt wurde. Daher war es absolut nicht nötig, diese Antwort zu schreiben.
Aadit M Shah

3
Ich lese gerne mehrere Antworten, manchmal macht die Formulierung der einen oder anderen einen Unterschied.

Ich dachte, es fügte hinzu, weil es mich wissen ließ, wofür dieser zweite Satz Klammern war. Zumindest war es hier klarer, dass ich sah.
Johnny

Meine Favoriten ans. Beide Enden der Probe IIFE haben Parameter, und die Zuordnung zwischen den beiden wird deutlich gemacht.
Stephen W. Wright

4

Fang hier an:

var b = 'bee';
console.log(b);  // global

Setzen Sie es in eine Funktion ein und es ist nicht mehr global - Ihr primäres Ziel.

function a() {
  var b = 'bee';
  console.log(b);
}
a();
console.log(b);  // ReferenceError: b is not defined -- *as desired*

Rufen Sie die Funktion sofort auf - oops:

function a() {
  var b = 'bee';
  console.log(b);
}();             // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'

Verwenden Sie die Klammern, um einen Syntaxfehler zu vermeiden:

(function a() {
  var b = 'bee';
  console.log(b);
})(); // OK now

Sie können den Funktionsnamen weglassen:

(function () {    // no name required
  var b = 'bee';
  console.log(b);
})();

Komplizierter muss es nicht sein.


2
Der Syntaxfehler spricht von Pfeilfunktionen. Soweit ich weiß, ist es eine neue Funktion von js, die es vor einigen Jahren noch nicht gab, aber die IIFE. Die Klammern wurden also wahrscheinlich ursprünglich verwendet, um einen Syntaxfehler zu vermeiden, aber einen anderen?
JCarlosR

Könnten Sie bitte die @ JCarlos-Frage beantworten? Da er zu Recht darauf hinweist, dass das IIFE viel vor der Pfeilfunktion stand, würde es helfen zu verstehen, warum die Verpackung erforderlich ist.
Script47

@ Script47 Ich habe keine Antwort auf JCarlos 'Frage im Kommentar. Sie könnten eine neue Frage formulieren und posten, und ich bin sicher, Sie werden einige gute Antworten erhalten.
Jim Flood

@JCarlos Wenn ich den ausführe, der den Fehler auslöst, wird die Pfeilfunktion Uncaught SyntaxError: Unexpected token )eher erwähnt als erwähnt. Könnten Sie möglicherweise eine Geige damit teilen, die den Pfeilfunktionsfehler auslöst?
Script47

2

Selbstausführende anonyme Funktion. Es wird ausgeführt, sobald es erstellt wurde.

Ein kurzes und dummes Beispiel, bei dem dies nützlich ist, ist:

function prepareList(el){
  var list = (function(){
    var l = []; 
    for(var i = 0; i < 9; i++){
     l.push(i);
    }
    return l;
  })();

  return function (el){
    for(var i = 0, l = list.length; i < l; i++){
      if(list[i] == el) return list[i];
    }
    return null;
  }; 
} 

var search = prepareList();
search(2);
search(3);

Anstatt jedes Mal eine Liste zu erstellen, erstellen Sie sie nur einmal (weniger Overhead).


1
Wie geschrieben, erstellt Ihre Suche die Liste bei jedem Aufruf neu. Um dies zu vermeiden, müssen Sie (1) die Liste erstellen und (2) die Suchfunktion als Abschluss zurückgeben, um Zugriff auf die gerade erstellte Liste zu erhalten. Dies können Sie ganz einfach mit dem anonymen selbstaufrufenden Formular tun. Siehe jsfiddle.net/BV4bT .
George

Kannst du erklären ... weniger Aufwand? Ich verstehe diesen Teil nicht
HIRA THAKUR

2
Gemeinkosten sind alle Arbeiten, die nicht erforderlich sind. Das Auffüllen eines Arrays bei jedem Funktionsaufruf ist nicht erforderlich. Aus diesem Grund wird ein Array im Beispiel von self-exec ausgefüllt. Nur zum ersten Mal anonyme Funktion. Es scheint jedoch, dass ich in meiner eigenen Antwort einen Fehler gemacht habe. Ein geeignetes Beispiel finden Sie unter dem Link in Georges Kommentar.
Usoban

2

Selbstausführende Funktionen werden normalerweise verwendet, um den Kontext zu kapseln und Namenskollusionen zu vermeiden. Alle Variablen, die Sie in (function () {..}) () definieren, sind nicht global.

Der Code

var same_name = 1;

var myVar = (function() {
    var same_name = 2;
    console.log(same_name);
})();

console.log(same_name);

erzeugt diese Ausgabe:

2
1

Mit dieser Syntax vermeiden Sie Kollisionen mit globalen Variablen, die an anderer Stelle in Ihrem JavaScript-Code deklariert sind.


1
Richtig, die Ausgabe wäre 2 und dann 1, da myVar zuerst ausgeführt wird
Dalibor

1
Ihre Erklärung erklärt den Funktionsumfang gut, erklärt jedoch nicht, warum er sofort ausgeführt wird. Das Zuweisen zu einer Variablen ist selbstzerstörerisch und kann auch beabsichtigen, dass es mehr als einmal ausgeführt werden kann. var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); Hätte das gleiche Ergebnis.
Domenicr

2

Es heißt IIFE - Sofort aufgerufener Funktionsausdruck. Hier ist ein Beispiel, um die Syntax und Verwendung zu zeigen. Es wird verwendet, um die Verwendung von Variablen nur bis zur Funktion und nicht darüber hinaus zu erfassen.

(function () {
  function Question(q,a,c) {
    this.q = q;
    this.a = a;
    this.c = c;
  }

  Question.prototype.displayQuestion = function() {
    console.log(this.q);
    for (var i = 0; i < this.a.length; i++) {
      console.log(i+": "+this.a[i]);
    }
  }

  Question.prototype.checkAnswer = function(ans) {
    if (ans===this.c) {
      console.log("correct");
    } else {
      console.log("incorrect");
    }
  }

  var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
  var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
  var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);

  var questions = [q1, q2, q3];

  var n = Math.floor(Math.random() * questions.length)

  var answer = parseInt(prompt(questions[n].displayQuestion()));
  questions[n].checkAnswer(answer);
})();

1

IIFE (Sofort aufgerufener Funktionsausdruck) ist eine Funktion, die ausgeführt wird, sobald das Skript geladen wird und verschwindet.

Betrachten Sie die folgende Funktion, die in einer Datei mit dem Namen iife.js geschrieben ist

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

Dieser obige Code wird ausgeführt, sobald Sie iife.js laden und ' Hello Stackoverflow! auf der Konsole der Entwicklertools.

Eine ausführliche Erläuterung finden Sie unter Sofort aufgerufener Funktionsausdruck (IIFE).


1

Ein weiterer Anwendungsfall ist die Memoisierung, bei der ein Cache-Objekt nicht global ist:

var calculate = (function() {
  var cache = {};
  return function(a) {

    if (cache[a]) {
      return cache[a];
    } else {
      // Calculate heavy operation
      cache[a] = heavyOperation(a);
      return cache[a];
    }
  }
})();

0

Ein sofort aufgerufener Funktionsausdruck (IIFE) ist eine Funktion, die ausgeführt wird, sobald sie erstellt wurde. Es besteht keine Verbindung zu Ereignissen oder zur asynchronen Ausführung. Sie können ein IIFE wie folgt definieren:

(function() {
     // all your code here
     // ...
})();

Das erste Klammerpaar function () {...} konvertiert den Code in den Klammern in einen Ausdruck. Das zweite Klammerpaar ruft die aus dem Ausdruck resultierende Funktion auf.

Eine IIFEkann auch als selbstaufrufende anonyme Funktion beschrieben werden. Am häufigsten wird der Umfang einer über var erstellten Variablen begrenzt oder der Kontext gekapselt, um Namenskollisionen zu vermeiden.


0

Der Grund, warum selbstaufrufende anonyme Funktionen verwendet werden, ist, dass sie niemals von einem anderen Code aufgerufen werden sollten, da sie den Code "einrichten", der aufgerufen werden soll (zusammen mit dem Geben von Funktionen und Variablen).

Mit anderen Worten, sie sind wie Programme, die zu Beginn des Programms "Klassen erstellen". Nachdem sie (automatisch) instanziiert wurden, sind nur die Funktionen verfügbar, die von der anonymen Funktion zurückgegeben werden. versteckte Funktionen sind noch vorhanden, zusammen mit jedem Status (Variablen, die während der Bereichserstellung festgelegt wurden).

Sehr cool.


0

Der folgende Code:

(function () {

})();

wird als sofort aufgerufener Funktionsausdruck bezeichnet (IIFE) bezeichnet.

Es wird als Funktionsausdruck bezeichnet, da der ( yourcode )Operator in Javascript ihn in einen Ausdruck zwingt. Der Unterschied zwischen einem Funktionsausdruck und einer Funktionsdeklaration ist folgender:

// declaration:
function declaredFunction () {}

// expressions:

// storing function into variable
const expressedFunction = function () {}

// Using () operator, which transforms the function into an expression
(function () {})

Ein Ausdruck ist einfach eine Menge Code, der zu einem einzelnen Wert ausgewertet werden kann . Bei den Ausdrücken im obigen Beispiel war dieser Wert ein einzelnes Funktionsobjekt .

Nachdem wir einen Ausdruck haben, der zu einem Funktionsobjekt ausgewertet wird, können wir das Funktionsobjekt sofort mit dem Operator aufrufen() . Zum Beispiel:

(function() {

  const foo = 10;        // all variables inside here are scoped to the function block
  console.log(foo);

})();

console.log(foo);  // referenceError foo is scoped to the IIFE

Warum ist das nützlich?

Wenn es sich um eine große Codebasis handelt und / oder wenn wir verschiedene Bibliotheken importieren, steigt die Wahrscheinlichkeit von Namenskonflikten. Wenn wir bestimmte Teile unseres Codes schreiben, die in einem IIFE verwandt sind (und daher dieselben Variablen verwenden), werden alle Variablen und Funktionsnamen in die Funktionsklammern des IIFE aufgenommen . Dies verringert die Wahrscheinlichkeit von Namenskonflikten und ermöglicht es Ihnen, sie nachlässiger zu benennen (z. B. müssen Sie ihnen kein Präfix voranstellen).


0

In der ES6-Syntax (für mich selbst posten, da ich immer wieder auf dieser Seite lande und nach einem kurzen Beispiel suche):

// simple
const simpleNumber = (() => {
  return true ? 1 : 2
})()

// with param
const isPositiveNumber = ((number) => {
  return number > 0 ? true : false
})(4)

0

Diese Funktion wird als selbstaufrufende Funktion bezeichnet. Eine selbstaufrufende (auch selbstausführende) Funktion ist eine namenlose (anonyme) Funktion, die unmittelbar nach ihrer Definition aufgerufen (aufgerufen) wird. Lesen Sie hier mehr

Diese Funktionen bewirken, dass bei der Definition der Funktion die Funktion sofort aufgerufen wird, was Zeit und zusätzliche Codezeilen spart (im Vergleich zum Aufrufen in einer separaten Zeile).

Hier ist ein Beispiel:

(function() {
    var x = 5 + 4;
    console.log(x);
})();



0

Es ist ein Funktionsausdruck und steht für sofort aufgerufenen Funktionsausdruck (IIFE). IIFE ist einfach eine Funktion, die direkt nach ihrer Erstellung ausgeführt wird. Nachdem die Funktion warten muss, bis sie zur Ausführung aufgerufen wird, wird IIFE sofort ausgeführt. Lassen Sie uns das IIFE anhand eines Beispiels konstruieren. Angenommen, wir haben eine Add-Funktion, die zwei Ganzzahlen als Argumente verwendet und die Summe zurückgibt. Lassen Sie uns die Add-Funktion in ein IIFE verwandeln.

Schritt 1: Definieren Sie die Funktion

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

Schritt 2: Rufen Sie die Funktion auf, indem Sie die gesamte Funktionsdeklaration in Klammern setzen

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

Schritt 3: Um die Funktion sofort aufzurufen, entfernen Sie einfach den 'Hinzufügen'-Text aus dem Aufruf.

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

Der Hauptgrund für die Verwendung eines IFFE besteht darin, einen privaten Bereich innerhalb Ihrer Funktion beizubehalten. In Ihrem Javascript-Code möchten Sie sicherstellen, dass Sie keine globale Variable überschreiben. Manchmal definieren Sie versehentlich eine Variable, die eine globale Variable überschreibt. Versuchen wir es mit einem Beispiel. Angenommen, wir haben eine HTML-Datei namens iffe.html und Codes innerhalb des Body-Tags sind:

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

Nun, der obige Code wird ohne jede Frage ausgeführt. Nehmen wir nun an, Sie haben versehentlich oder absichtlich eine Variable mit dem Namen document deklariert.

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
        const document = "hi there";
        console.log(document);
    </script> 
</body>

Sie werden in einem SyntaxError enden : Neudeklaration eines nicht konfigurierbaren globalen Eigenschaftendokuments.

Wenn Sie jedoch einen Variablennamen documet deklarieren möchten, können Sie dies mithilfe von IFFE tun.

<body>
    <div id = 'demo'></div>
    <script>
        (function(){
            const document = "hi there";
            this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
            console.log(document);
        })();
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

Ausgabe:

Geben Sie hier die Bildbeschreibung ein

Nehmen wir ein anderes Beispiel an. Nehmen wir an, wir haben ein Taschenrechnerobjekt wie unten.

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
    </script> 
</body>

Nun, es funktioniert wie ein Zauber. Was ist, wenn wir versehentlich den Wert des Taschenrechnerobjekts neu zuweisen?

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
        calculator = "scientific calculator";
        console.log(calculator.mul(5,5));
    </script> 
</body>

Ja, Sie erhalten einen TypeError: calculator.mul ist keine Funktion iffe.html

Mit Hilfe von IFFE können wir jedoch einen privaten Bereich erstellen, in dem wir einen anderen Variablennamenrechner erstellen und verwenden können.

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        var cal = (function(){
            var calculator = {
                sub:function(a,b){
                    return a-b;
                },
                div:function(a,b){
                    return a/b;
                }
            }
            console.log(this.calculator.mul(5,10));
            console.log(calculator.sub(10,5));
            return calculator;
        })();
        console.log(calculator.add(5,10));
        console.log(cal.div(10,5));
    </script> 
</body>

Ausgabe: Geben Sie hier die Bildbeschreibung ein


-1

Ich denke, die 2 Sätze von Klammern machen es ein bisschen verwirrend, aber ich habe eine andere Verwendung im Google-Beispiel gesehen, sie haben etwas Ähnliches verwendet. Ich hoffe, dies wird Ihnen helfen, besser zu verstehen:

var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);

Wenn dies windows.appnicht definiert ist, window.app = {}wird es sofort ausgeführt und daher während der Bedingungsbewertung window.appzugewiesen. {}Das Ergebnis ist also beides appund wird window.appjetzt. Die {}Konsolenausgabe lautet also:

Object {}
Object {}

-1

Normalerweise rufen wir eine Funktion nicht sofort auf, nachdem wir sie in das Programm geschrieben haben. In extrem einfachen Worten, wenn Sie eine Funktion direkt nach ihrer Erstellung aufrufen, heißt sie IIFE - ein ausgefallener Name.


-1

Normalerweise hat JavaScript-Code einen globalen Gültigkeitsbereich in der Anwendung. Wenn wir darin eine globale Variable deklarieren, besteht die Möglichkeit, dass dieselbe doppelte Variable in einem anderen Bereich der Entwicklung für einen anderen Zweck verwendet wird. Aufgrund dieser Duplizierung kann ein Fehler auftreten. Damit wir diese globalen Variablen vermeiden können, indem wir den Funktionsausdruck sofort aufrufen, ist dieser Ausdruck ein selbstausführender Ausdruck. Wenn wir unseren Code in diesem IIFE erstellen Ausdruck , entspricht die globale Variable dem lokalen Bereich und der lokalen Variablen.

Zwei Möglichkeiten, wie wir IIFE erstellen können

(function () {
    "use strict";
    var app = angular.module("myModule", []);
}());

ODER

(function () {
    "use strict";
    var app = angular.module("myModule", []);
})();

Im obigen Code-Snippet ist " var app " jetzt eine lokale Variable.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.