Function Expression vs Declaration: ¿qué elegir en JavaScript?

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Por qué esta pregunta atormenta incluso a desarrolladores experimentados?

\n

Si alguna vez has escrito en JavaScript, seguro que te has encontrado con ambas formas de declarar funciones. Se ven similares, pero se comportan de manera completamente diferente. En Stack Overflow, esta pregunta ha acumulado miles de visitas y decenas de páginas de discusión. ¿Por qué? Porque no entender la diferencia entre var functionName = function() {} y function functionName() {} provoca errores difíciles de detectar.

\n

Hoy vamos a aclarar este tema de una vez por todas. Aprenderás qué son function declaration y function expression, cómo funciona el hoisting y cuándo usar cada método. ¡Allá vamos!

\n\n

¿Qué se esconde detrás de la sintaxis?

\n

Empecemos por lo básico. La primera opción es Function Declaration (declaración de función):

\n
function greet() {\n    console.log('¡Hola!');\n}
\n

La segunda es Function Expression (expresión de función):

\n
const greet = function() {\n    console.log('¡Hola!');\n};
\n

Observa: en el primer caso, la función tiene un nombre y está al inicio de la línea. En el segundo, asignamos una función anónima a la variable greet. Pero lo más interesante comienza cuando vemos cómo JavaScript procesa estas declaraciones.

\n\n

La diferencia principal: Hoisting (elevación)

\n

Hoisting es un mecanismo de JavaScript mediante el cual las declaraciones de variables y funciones se mueven al inicio de su ámbito de visibilidad antes de ejecutar el código. Pero funciona de manera diferente para declaration y expression.

\n\n

Function Declaration se eleva por completo

\n

Cuando usas function functionName() {}, JavaScript «eleva» toda la declaración de la función. Esto significa que puedes llamar a la función antes de que esté declarada en el código:

\n
sayHello(); // "¡Hola!"\n\nfunction sayHello() {\n    console.log('¡Hola!');\n}
\n

El código se ejecutará sin errores. Es práctico, pero puede confundir a los principiantes.

\n\n

Function Expression no se eleva

\n

Con var functionName = function() {} la historia es diferente. Solo se eleva la declaración de la variable, pero no su valor. La función permanece en su lugar:

\n
sayHello(); // TypeError: sayHello is not a function\n\nvar sayHello = function() {\n    console.log('¡Hola!');\n};
\n

¿Por qué sucede esto? Porque var eleva la declaración de la variable sayHello (con el valor undefined), y la asignación de la función ocurre solo en la línea de la expresión. Por lo tanto, antes de esa línea, sayHello es undefined, e intentar llamarlo como función provoca un error.

\n\n

Por cierto, si reemplazas var por let o const, el error será diferente: ReferenceError: Cannot access 'sayHello' before initialization. Esto se debe a que let y const no se inicializan hasta el momento de la declaración (la llamada «zona muerta temporal»).

\n\n

Ámbito de visibilidad: otra piedra en el camino

\n

Tanto function declaration como function expression siguen las reglas del ámbito de visibilidad. Pero hay un matiz.

\n\n

Function Declaration es visible dentro del bloque

\n

Aunque function declaration se eleva, su ámbito de visibilidad está limitado al bloque (en modo estricto):

\n
'use strict';\nif (true) {\n    function greet() {\n        console.log('Dentro del bloque');\n    }\n    greet(); // "Dentro del bloque"\n}\ngreet(); // ReferenceError: greet is not defined (en modo estricto)
\n

En modo no estricto, esta declaración «se sale» del bloque, pero no es recomendable confiar en ello.

\n\n

Function Expression vive en su variable

\n

Con function expression todo es predecible: la función solo está disponible donde la variable es accesible. Si se mueve

Blogs

Book Recommendations