Hoisting en JavaScript

Hoisting

En la mayoría de los lenguajes de programación, el ámbito/alcance/scope de una variable está en el bloque donde fue definida (block-level scope), por ejemplo, dentro de un bloque if, for, while; sin embargo en JavaScript (ECMAScript 5.1) esto no es así, puesto que el alcance de una variable está en la función en donde fue declarada (function-level scope).

¿Qué es hoisting?

El hoisting o “elevamiento” es una de las particularidades de JavaScript y ocurre cuando declaramos una variable dentro de una función (su scope), entonces el intérprete* interno mueve la declaración (creación) de la variable al inicio de la función.

    (function () {
        for(var x = 0; x < 3; x += 1) {
            console.log(x);
        }
        console.log(x, "todavía existe!!");
    }());

😕 ¿Que es lo que ocurrió?, como se mencionó anteriormente, el intérprete* interno mueve la declaración de variables al comienzo de su scope. Veamos lo que ocurre realmente en el browser:

    (function () {
        var x; // <- la variable es elevada
        for(x = 0; x < 3; x += 1) {
            console.log(x);
        }
        console.log(x, "todavía existe!!");
    }());
Ahora observemos con más detalle el siguiente ejemplo:
    var x = 5;

    (function () {
        console.log("x:", x); //se espera 5
        var x = 10;
        console.log("x:", x); //se espera 10
    }());

o_O Nuevamente ocurre algo inesperado, ya que la primera vez que imprimimos la variable x, se esperaba 5 (el valor de la variable global), sin embargo obtuvimos undefined. Así es como lo interpreta el browser: 💡

    var x = 5;

    (function () {
        var x; //  undefined
        x = 10;
        console.log("x:", x); //-> 10
    }());

hoisting

➡ Probemos el siguiente caso con funciones:

    console.log("fn1", fn1()); //que imprime?
    console.log("fn2", fn2()); //que imprime?

    //function expression
    var fn1 = function() { return 1; };

    //function declaration
    function fn2() { return 2; }

😮 Nuevamente el hoisting haciendo de las suyas. Cuando creamos una función con la sintaxis function declaration, la declaración y la definición de la función son elevadas, pero cuando utilizamos la sintaxis function expression, sólo se eleva la declaración, no su definición.

    var fn1; // <- la variable es elevada
    function fn2() { return 2; } // <- declaración y definición son elevadas

    console.log("fn1", fn1()); // TypeError: undefined is not a function
    console.log("fn2", fn2()); // 2

    //function expression
    fn1 = function() { return 1; };

Resumiendo

Como la declaración de variables es procesada antes que cualquier código sea ejecutado, declarar una variable en cualquier parte es lo mismo que declararla al inicio. Esto significa que una variable puede ser usada antes de su declaración, como lo vimos en los ejemplos anteriores. Por lo tanto, la buena práctica es declarar las variables al inicio de su scope, es decir, al inicio de la función.

⭐ Recomiendo leer los siguientes artículos:

A tener en cuenta

ECMAScript 6 (ES2015) ya soporta variables block-level scope mediante los keyword let y const.

😎 Happy coding!

Advertisements

8 thoughts on “Hoisting en JavaScript

  1. María says:

    La verdad que despues de varias lecturas con tu texto logré entender que es el hoisting.
    Muchas gracias!!
    María.

Comentarios

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s