En este tutorial vamos a ver una breve explicación acerca de lo que es el hoisting en JavaScript. Antes de que JavaScript ejecute el código que has programado, lo analiza y lo interpreta, agregando a la memoria todas y cada una de las funciones y variables que encuentra, manteniendo estos elementos en memoria hasta que finaliza la ejecución del script. A la metodología que JavaScript sigue para realizar esta tarea es a lo que se le llama hoisting.
Existen diferentes tipos de comportamiento para la declaración de funciones o la declaración de expresiones. Cuando declaras una función, podrás utilizarla antes de que sea declarada en el código, que funcionará a la perfección la mayor parte de las veces. Sin embargo, algunas expresiones provocarán errores. Veamos por qué.
Qué es el hoisting
JavaScript es un lenguaje interpretado, por lo que es de esperar que el intérprete de JavaScript ejecute y procese las líneas de código una por una, de arriba hacia abajo. Sin embargo, esto no ocurre así, ya que las JavaScript siempre junta todas las variables globales y las sitúa encima del documento, independientemente del lugar donde estén definidas. En cuanto a las variables de un método o de una función, las mueve al principio de la misma, también con independencia del lugar donde estén definidas en el contexto de dicha función.
Sin embargo, JavaScript no hace esto con las funciones, por lo que cuando asignas una función a una variable, debido al efecto del hoisting, tendrá inicialmente un valor no definido.
Como regla general, es recomendable que siempre declares las funciones, las variables o cualquier objeto antes de utilizarlo. Sin embargo, vamos a ver lo que ocurre en diferentes escenarios. Si no has entendido en qué consiste el hosting, cosa que tampoco yo hubiese entendido con este rollo, no te preocupes, ya que en breve lo tendrás muy claro.
Hoisting en funciones
A continuación puedes ver un ejemplo mediante el cual explicamos el hoisting en funciones. Por ejemplo, vamos a partir de la siguiente función:
function saludo() {
alert('Hola, colega!');
}
Debido a las ventajas del hositing en JavaScript, podrías usar la función saludo()
antes de que sea declarada en el código, tal y como hacemos aquí:
saludo();
function saludo() {
alert('Hola, colega!');
}
Esto no provocará ningún error, mostrándose por pantalla el testo «Hola, colega!», como es de esperar.
Hoisting en variables
El código que era válido cuando declarábamos una función, no es válido cuando usamos una expresión, tal y como hacemos en el siguiente ejemplo:
saludo();
var saludo = function() {
alert('Hola, colega!');
}
En este caso, tenemos una función, pero está asignada a una variable. Debido a las reglas del hositing, la variable saludo tendrá el valor undefined
hasta que JavaScript interprete dicha parte del código. De modo que si ejecutas el código anterior, obtendrás el siguiente error:
TypeError: saludo is not a function
Tal y como has visto, hemos usado una variable declarada con var
. Si hubiésemos usado const
o let
, hubiésemos obtenido también un error, aunque algo diferente, que ni const
ni let
se inicializan con el valor undefined
por defecto.
Vamos proponer un ejemplo en el que usamos const
:
const saludo = function() {
alert('Hola, colega!');
}
Y también otro ejemplo en el que usamos let
:
let saludo = function() {
alert('Hola, colega!');
}
En cualquiera de estos dos casos, obtendremos un error de referencia cuando usemos la función saludo()
antes de que esta sea declarada:
ReferenceError: Cannot access 'saludo' before initialization
Si en lugar de asignar una función a la variable o a la constante hubiésemos asignado un objeto o una clase, también habríamos obtenido un error. En el caso concreto de las clases, estas no se inicializan cuando son asignadas a una variable, por lo que obtendríamos un error de referencia:
ReferenceError: <Clase> is not defined
Si quieres evitarte problemas, es recomendable que siempre declares las variables al principio de tus funciones o de tus clases para que así el intérprete interno de JavaScript no te juegue una mala pasada.
Y esto ha sido todo.