Self Executing Functions oder IIFE – selbst ausführende Funktionen

Javascript IIFE, auch Self Executing Funktions

(function() {}) () – self executing functions oder selbst ausführende Funktionen – schützen ihre lokalen Variablen vor allem, was sonst so auf der Seite passiert.

Ein anderer Name für dieses Konstrukt ist Immediately Invoked Function Expression (IIFE) – sofort aufgerufener Funktions-Ausdruck.

Abschirmung

Sofort ausgeführte Funktionen erzeugen eine Abschirmung, unter der die Funktionen und Variablen nach außen – also global – nicht sichtbar sind. Es gibt zwei Schreibweisen, beide mit einer Inflation von runden Klammern:

(function(){
    let test = true;
})();
(function() { 
    let test = true;
} () );

Variablen und Funktionen innerhalb von IIFE können außerhalb der IIFE nicht angesprochen werden, sie sind sozusagen privates Eigentum der selbst ausführenden Funktionen. Denken wir nur einmal daran, wie viele Scripte eine Funktion init nennen!

(function IIFE_slideshow () {
   let slides;
   let position;
	
   function init() {
      console.log ("iife " );
   }

   init();
})();

Schutz der Variablen

Die Variable test ist außerhalb der Funktion nicht sichtbar. So kommt es zwischen den Scripten innerhalb einer Seite nicht zu Interferenzen, selbst wenn sie dieselben Variablennamen und Namen für private Funktionen benutzen.

Sofort ausführbare Funktionen werden direkt an Ort und Stelle ausgeführt, so als wären sie eine einzelne Anweisung. Wenn die Funktion abgearbeitet ist, sind alle Variablen der Funktion vergessen. Das hält den Namensraum sauber und räumt den Speicher frei.

Selbst-ausführende Funktionen verfolgen ein ähnliches Konzept wie anonyme Funktionen.

var foo = function() {
 /* Anweisungen */ 
}

oder – ein bekanntes Muster –

document.getElementById('foo').onclick = function () {
 /* Anweisungen */ 
}

Anonyme Funktionen werden beim Aufruf einer Variablen zugewiesen, so dass sie nicht wirklich anonym sind. Immediately Invoked Function Expressions oder Self Executing Functions brauchen ein paar Klammern mehr – erst dann sind sie wirklich anonym.

Wieso die vielen Klammern?

Die Deklaration einer Funktion – function foo() {} – ist kein ausführbarer Ausdruck. Erst der Aufruf mit dem Namen gefolgt von runden Klammern erzeugt den ausführbaren Ausdruck: foo().

Um eine anonyme Funktion direkt an Ort und Stelle auszuführen, muss der Parser erkennen, dass er einen Ausdruck vor sich hat und keine Deklaration einer Funktion. Eine Form der Notation sind die runden Klammern rund um die Funktion – in Javascript können Ausdrücke nicht in Klammern sitzen.

(function() {
    /* Anweisungen */ 
}) ();

setTimeout in Self Executing Function

Wird ein String als Argument übergeben, versucht Javascript diesen String zu evaluieren, wenn der Timeout feuert. Das wäre im globalen Bereich, in dem die Methode nicht existiert.

setTimeout ("changeImg()", time);

Stattdessen

setTimeout (changeImg, time);
Vanilla Javascript Slideshow mit setTimeout
Minimale Slideshow mit Vanilla Javascript
(function () {
let i = 0;
let images = [];
let time = 3000;

images [0] = "bird1.png";
images [1] = "bird2.png";
images [2] = "bird3.png";

function changeImg () {
    document.querySelector(".slide").src = images[i];
	
    if ( i < images.length - 1) {
        i++;
    } else {
        i = 0;
    }
    setTimeout (changeImg, time);
}

window.onload = changeImg;
})();

Verkürzte Schreibweise

Wenn man sich nicht um einen Return Value kümmern muss und es unrelevant ist, dass der Code etwas schwerer lesbar wird, kann man ein Byte sparen, indem man einen Unary Operator-Präfix vor die Funktion setzt.

!function(){ /* Anweisungen */ }();

Das ist ein vertrautes Muster: So beginnen Libraries wie jQuery und viele andere kleine Helfer.

/* Smooth Scroll with ankers*/
!function(e,t){"function"==typeof define&&define.amd?define([]

/*! jQuery v1.12.0 | (c) jQuery Foundation | jquery.org/license */
!function(a,b){"object"==typeof module&&"object"==t

IIFE mit Return-Wert

IIFEs können einen Namen haben und auch einen Return-Wert abliefern.

let result = (function IIFE_slideshow () {
   let slides;
   let position;
	
   function init() {
      console.log ("iife " );
   }
	
   init();
	
   return "Grüße von IIFE";
})();

console.log (result);