
!function(){}(): cos'è e perché si scrive così una IIFE
Cos'è una IIFE, perché a volte inizia con !, + o void prima di function, e dove si trova ancora oggi nel codice JavaScript.
Che cos’è una IIFE?
Capita di trovare in una libreria minificata o in un vecchio script una riga così
!(function () {
console.log("Ciao!");
})();
Sembra un errore di battitura — un punto esclamativo davanti a function — ma è del tutto intenzionale. Questa è una IIFE, acronimo di Immediately Invoked Function Expression: una funzione che viene definita e invocata immediatamente, nello stesso istante.
La forma più comune, quella che si insegna di solito, è questa:
(function () {
console.log("Ciao!");
})();
Le parentesi tonde intorno alla funzione, seguite da un’altra coppia di parentesi che la invoca. Ma perché !function(){}() funziona allo stesso modo? E soprattutto, perché non basta scrivere semplicemente function(){}()?
Il problema: dichiarazione vs espressione
Prova a scrivere questo in un file JavaScript:
function () {
console.log("Ciao!");
}();
Ottieni un errore di sintassi. Il motivo è che il motore JavaScript, quando trova la parola chiave function all’inizio di uno statement, si aspetta una dichiarazione di funzione (function nome() {}), non un’espressione. Una dichiarazione di funzione non può essere invocata inline subito dopo la sua definizione: quel () finale non ha senso per il parser in quel contesto.
Per far sì che JavaScript interpreti function(){} come espressione di funzione (qualcosa che produce un valore, quindi invocabile), bisogna far capire al parser che non ci troviamo all’inizio di uno statement. Il modo più noto è racchiudere tutto tra parentesi:
(function () {})();
Ma non è l’unico.
Il trucco degli operatori unari
Qualsiasi operatore unario messo prima di function ottiene lo stesso effetto, perché uno statement non può iniziare con un operatore come !, +, - o void. Il parser capisce quindi che sta leggendo un’espressione, e la funzione che segue viene trattata come function expression invocabile.
!(function () {
console.log("Eseguita con !");
})();
+(function () {
console.log("Eseguita con +");
})();
void (function () {
console.log("Eseguita con void");
})();
Tutte e tre le forme eseguono la funzione immediatamente, esattamente come (function(){})(). Cambia solo il valore restituito dall’intera espressione, che nella pratica quasi nessuno usa:
!function(){}()restituiscetrue(la negazione diundefined, che è falsy).+function(){}()prova a convertire il valore di ritorno in numero (di solitoNaN, perchéundefinednon è convertibile).void function(){}()restituisce sempreundefined, per costruzione — se questo ti suona familiare, è lo stesso principio dell’operatorevoidspiegato injavascript:void(0), cos’è?.
ℹ️ Occhio al valore di ritorno
Se la tua IIFE deve restituire qualcosa che userai davvero (non solo eseguire codice per gli effetti collaterali), evita !/+ e usa le classiche parentesi (function(){ return x; })().
Dove si trova ancora oggi
Questo pattern compare soprattutto in:
- Librerie minificate o UMD wrapper, dove ogni carattere risparmiato conta e
!functionè un byte più corto di(function. - Script concatenati senza bundler, dove il carattere iniziale funge anche da protezione: se lo script precedente non termina con un punto e virgola, un’espressione che inizia con
(rischierebbe di essere interpretata come una chiamata di funzione sullo script precedente. Iniziare con!,+ovoidevita l’ambiguità. - Vecchio codice jQuery/plugin, dove l’obiettivo era creare uno scope isolato senza inquinare il namespace globale.
Meglio le alternative moderne
Con i moduli ES (import/export), ogni file ha già il proprio scope isolato: non serve più avvolgere il codice in una IIFE solo per evitare variabili globali. Se stai scrivendo codice nuovo con un bundler moderno, preferisci i moduli. La IIFE resta comunque utile da riconoscere quando la incontri in codice legacy o in bundle di terze parti.

Co-Fondatore & CTO presso PAPION. Senior full-stack engineer specializzato in React, TypeScript, Node.js e sicurezza applicativa.