Diego Betto's Blog
Foto di Emily Morter su Unsplash

Diego Betto · September 6, 2026 · 3 min di lettura

!function(){}(): what it is and why an IIFE is written that way

What an IIFE is, why it sometimes starts with !, + or void before function, and where it still shows up in JavaScript code today.

Condividi:XLinkedInFacebookWhatsApp

What is an IIFE?

You’ll sometimes find a line like this in a minified library or an old script

!(function () {
  console.log("Hi!");
})();

It looks like a typo — an exclamation mark in front of function — but it’s entirely intentional. This is an IIFE, short for Immediately Invoked Function Expression: a function that gets defined and invoked in the same instant.

The most common form, the one usually taught, is this:

(function () {
  console.log("Hi!");
})();

Parentheses around the function, followed by another pair that invokes it. But why does !function(){}() work the same way? And more importantly, why doesn’t simply writing function(){}() work?

The problem: declaration vs. expression

Try writing this in a JavaScript file:

function () {
  console.log("Hi!");
}();

You get a syntax error. The reason is that the JavaScript engine, when it finds the function keyword at the start of a statement, expects a function declaration (function name() {}), not an expression. A function declaration can’t be invoked inline right after its definition: that trailing () doesn’t make sense to the parser in that context.

To make JavaScript treat function(){} as a function expression (something that produces a value, and is therefore callable), you need to signal to the parser that you’re not at the start of a statement. The best-known way is to wrap the whole thing in parentheses:

(function () {})();

But it’s not the only one.

The unary-operator trick

Any unary operator placed before function achieves the same effect, because a statement can’t start with an operator like !, +, -, or void. The parser therefore understands it’s reading an expression, and the function that follows is treated as a callable function expression.

!(function () {
  console.log("Run with !");
})();

+(function () {
  console.log("Run with +");
})();

void (function () {
  console.log("Run with void");
})();

All three forms execute the function immediately, exactly like (function(){})(). The only difference is the value returned by the whole expression, which in practice almost nobody uses:

  • !function(){}() returns true (the negation of undefined, which is falsy).
  • +function(){}() tries to convert the return value to a number (usually NaN, since undefined isn’t convertible).
  • void function(){}() always returns undefined by construction — if that sounds familiar, it’s the same principle behind the void operator explained in javascript:void(0), what is it?.

ℹ️ Watch the return value

If your IIFE needs to return something you’ll actually use (not just run code for its side effects), skip !/+ and use the classic parentheses form (function(){ return x; })().

Where it still shows up today

This pattern mostly appears in:

  • Minified libraries or UMD wrappers, where every saved character counts and !function is one byte shorter than (function.
  • Concatenated scripts without a bundler, where the leading character also acts as a safety net: if the previous script doesn’t end with a semicolon, an expression starting with ( risks being parsed as a function call on the previous script. Starting with !, +, or void avoids the ambiguity.
  • Old jQuery/plugin code, where the goal was to create an isolated scope without polluting the global namespace.

Modern alternatives are better

With ES modules (import/export), every file already has its own isolated scope: you no longer need to wrap code in an IIFE just to avoid global variables. If you’re writing new code with a modern bundler, prefer modules. The IIFE is still worth recognizing when you run into it in legacy code or third-party bundles, though.

Condividi:XLinkedInFacebookWhatsApp
Diego Betto

Written by

Diego Betto

Co-Founder & CTO at PAPION. Senior full-stack engineer specializing in React, TypeScript, Node.js, and application security.