Command Palette

Search for a command to run...

IIFE: Expresiones de Función Invocadas Inmediatamente

Aprende qué son las IIFE, cómo funcionan, por qué se usaban para crear ámbitos privados, y cuándo tienen sentido en JavaScript moderno con módulos ES6.

Lectura: 9 min
Nivel: Principiante

TL;DR - Resumen rápido

  • IIFE: Immediately Invoked Function Expression
  • Funciones que se ejecutan inmediatamente después de ser definidas
  • Crean un ámbito privado para encapsular variables
  • Evitan contaminación del ámbito global
  • Solo funcionan con expresiones de función, no declaraciones
  • Menos necesarias con módulos ES6 pero aún útiles en ciertos casos

¿Qué es una IIFE?

IIFE es el acrónimo de "Immediately Invoked Function Expression" (Expresión de Función Invocada Inmediatamente). Es un patrón en JavaScript donde defines una función y la invocas inmediatamente en la misma expresión. Las IIFE se usan principalmente para crear un ámbito privado y evitar la contaminación del ámbito global con variables y funciones.

El concepto clave es que la función se ejecuta inmediatamente después de ser creada, sin necesidad de ser asignada a una variable o ser llamada posteriormente. Esto crea un ámbito temporal que existe solo durante la ejecución de la IIFE, y cualquier variable declarada dentro de ella no es accesible desde fuera.

Expresión vs Declaración

Las IIFE solo funcionan con expresiones de función, no con declaraciones. Los paréntesis externos convierten la declaración en una expresión, lo que permite invocarla inmediatamente. Las declaraciones de función no pueden ser invocadas directamente.

Sintaxis básica

La sintaxis de una IIFE tiene dos partes: la expresión de función envuelta en paréntesis, y los paréntesis de invocación al final. Los paréntesis externos son necesarios para que el parser de JavaScript trate la función como una expresión en lugar de una declaración.

sintaxis-basica.js
Loading code...

El ejemplo muestra la sintaxis clásica de una IIFE. La función está envuelta en paréntesis para convertirla en una expresión, y los paréntesis finales () la invocan inmediatamente. También puedes usar el operador !, +, -, o ~ antes de la función para forzar que sea tratada como expresión, aunque el estilo con paréntesis es más común y legible.

  • <strong>Paréntesis externos:</strong> <code>(function() {...})()</code> - estilo más común
  • <strong>Operador unario:</strong> <code>!function() {...}()</code> - menos legible
  • <strong>Invocación interna:</strong> <code>(function() {...}())</code> - variante válida
  • <strong>Arrow function:</strong> <code>(() => {...})()</code> - sintaxis moderna

Legibilidad vs Concisión

Aunque existen múltiples sintaxis para crear IIFE, la versión con paréntesis externos (function() {...})() es la más legible y ampliamente reconocida. Prefiere esta sintaxis a menos que tengas una razón específica para usar otra.

Crear ámbito privado

Una de las principales razones para usar IIFE es crear un ámbito privado para variables y funciones. En JavaScript antes de ES6 (antes de let y const), las variables declaradas con var tenían ámbito de función, no de bloque. Las IIFE permitían crear un ámbito temporal sin contaminar el ámbito global.

ambito-privado.js
Loading code...

El ejemplo muestra cómo las variables declaradas dentro de una IIFE no son accesibles desde fuera. La variable secreto existe solo dentro del ámbito de la IIFE y no contamina el ámbito global. Esto es útil para encapsular lógica y evitar conflictos de nombres con otras partes del código.

Encapsulación

Las IIFE proporcionan encapsulación similar a los módulos modernos. Puedes exponer solo lo necesario asignando propiedades a window o retornando un objeto con la API pública.

Evitar contaminación global

En el pasado, cuando JavaScript no tenía módulos, las IIFE eran esenciales para evitar la contaminación del ámbito global. Múltiples scripts en una página podían tener conflictos si declaraban variables con el mismo nombre. Las IIFE resolvían esto creando ámbitos privados para cada script o biblioteca.

evitar-contaminacion.js
Loading code...

El ejemplo muestra dos IIFE que cada una define su propia variable contador sin conflicto. Cada IIFE tiene su propio ámbito privado, y las variables no interfieren entre sí. Este patrón era fundamental antes de los módulos ES6 para organizar código en aplicaciones grandes.

Módulos ES6 vs IIFE

Con la introducción de módulos ES6, las IIFE son menos necesarias para evitar contaminación global. Los módulos ya proporcionan ámbito privado por defecto. Sin embargo, las IIFE siguen siendo útiles en scripts que no usan módulos o en situaciones específicas.

IIFE con parámetros

Las IIFE pueden aceptar parámetros igual que cualquier otra función. Esto es útil para pasar valores globales al ámbito privado, o para crear closures con valores específicos capturados en el momento de la invocación.

iife-parametros.js
Loading code...

El ejemplo muestra cómo pasar parámetros a una IIFE. La variable global nombreGlobal se pasa como parámetro a la IIFE, creando una copia local dentro del ámbito privado. Esto es útil para capturar el valor de una variable en un momento específico, especialmente en bucles donde el valor puede cambiar.

Capturar valores en bucles

Las IIFE con parámetros son útiles en bucles para capturar el valor de una variable en cada iteración. Sin IIFE, todas las iteraciones compartirían la misma referencia a la variable, causando bugs sutiles.

IIFE que retornan valores

Las IIFE pueden retornar valores, lo que permite asignar el resultado a una variable. Este patrón es útil para crear objetos con métodos privados, configurar valores iniciales, o implementar el patrón Module en JavaScript.

iife-return.js
Loading code...

El ejemplo muestra una IIFE que retorna un objeto con métodos. Las variables contador y nombre son privadas y solo accesibles a través de los métodos retornados. Este es el patrón Module, que permite crear APIs públicas con estado privado encapsulado.

El patrón Module aprovecha las closures y el retorno de objetos para crear verdadera encapsulación. El estado privado (variables encapsuladas dentro de la IIFE) no es accesible desde fuera, mientras que la API pública (métodos expuestos a través del objeto retornado) proporciona la interfaz para interactuar con ese estado. Este patrón fue la base de muchos sistemas de módulos en JavaScript antes de ES6, y sigue siendo útil para entender cómo funcionan las closures y la encapsulación en el lenguaje.

Casos de uso modernos

Con la introducción de módulos ES6 y let/const, las IIFE son menos necesarias que antes. Sin embargo, siguen teniendo casos de uso válidos en JavaScript moderno, especialmente en situaciones donde necesitas un ámbito temporal o ejecución inmediata.

casos-uso.js
Loading code...

El ejemplo muestra casos de uso modernos para IIFE: inicialización de código que no necesita persistir, creación de closures en bucles, y ejecución de código asíncrono inmediato. Aunque los módulos ES6 han reducido la necesidad de IIFE para encapsulación, siguen siendo útiles para ejecución inmediata y creación de ámbitos temporales.

  1. <strong>Inicialización:</strong> Código que se ejecuta una vez y no necesita persistir
  2. <strong>Closures en bucles:</strong> Capturar valores en cada iteración
  3. <strong>Async IIFE:</strong> Usar async/await en el nivel superior de módulos
  4. <strong>Scripts sin módulos:</strong> Código que no puede usar módulos ES6
  5. <strong>Testing:</strong> Crear entornos aislados para pruebas

Async IIFE

Las IIFE con async/await son útiles para ejecutar código asíncrono en el nivel superior de módulos o scripts. Esto permite usar await sin estar dentro de una función async explícita.

Resumen

Resumen: IIFE (Immediately Invoked Function Expression)

Conceptos principales:

  • IIFE: función que se ejecuta inmediatamente después de ser definida
  • Solo funcionan con expresiones, no declaraciones
  • Crean ámbito privado para encapsular variables
  • Evitan contaminación del ámbito global
  • Pueden aceptar parámetros y retornar valores
  • Base del patrón Module en JavaScript

Casos de uso:

  • Encapsulación antes de módulos ES6
  • Evitar conflictos de nombres globales
  • Crear closures con valores capturados
  • Async IIFE para código asíncrono inmediato
  • Inicialización de código temporal
  • Scripts que no pueden usar módulos