RSS Feed

Alcance de Variables (var scope)

4

octubre 29, 2011 by - @pjnovas

En javascript las variables son inicializadas con undefined, pero ante una segunda declaracion no se inicializan nuevamente, si bien javascript nos permite declarar dos veces la misma variable, no es recomendable hacerlo. Pero si declaramos dos o mas veces la misma variable, a partir de la segunda declaración que lee el interpretador comprueba que ya esté declarada y no le modifica su valor ha no ser que esté implicito.

var baz;
console.log(baz); //baz === undefined

var foo = 100;
var foo;
console.log(foo); //foo === 100

Las variables en javascript, como en otros lenguajes, poseen un alcance al momento de su declaración indicando donde la puedo utilizar, pero a diferencia de otros lenguajes, en javascript el alcance es por función y no tenemos un alcance de variable por bloque (block-scope), como podría ser un if, for, while, etc. En estos casos la variable sigue teniendo un alcance a su función. Por ejemplo:

function unaFuncion(){
    var i = 100;

    console.log(unaVar); //unaVar === undefined
    console.log(otraVar); //otraVar === undefined

    if (!unaVar) {
        var unaVar = true;
    }
    var otraVar = 'otra variable';

    console.log(unaVar); //unaVar === true
    console.log(otraVar); //otraVar === 'otra variable'
}


En el ejemplo anterior declaramos una variable adentro de un if y la leemos luego por fuera. En otros lenguajes ni siquiera compila devolviendo un mensaje de error como “unaVar no está declarada” en la linea 4.
Esto demuestra que javascript no tiene un alcance de variable a nivel de bloque. Pero como es que funciona entonces?: simple, el interpretador alza la declaracion de la variable hasta el principio de la función, de esta manera la tendremos declarada al alcance de toda la función.
Usando el ejemplo anterior, será interpretado de la siguiente manera:

function unaFuncion(){
    var unaVar, otraVar;
    var i = 100;

    console.log(unaVar); //unaVar === undefined
    console.log(otraVar); //otraVar === undefined

    if (!unaVar) {
        unaVar = true;
    }
    otraVar = 'otra variable';

    console.log(unaVar); //unaVar === true
    console.log(otraVar); //otraVar === 'otra variable'
}

Dicho esto, los siguientes ejemplos funcionan de la misma manera sin afectar rendimiento, ni uso de memoria:

function miFuncionA(){
    var unaVar;
    for(var i=0; i<100; i++){
       unaVar = 'algun valor';
    }

    console.log(unaVar);
}
function miFuncionB(){
    for(var i=0; i<100; i++){
       var unaVar = 'algun valor';
    }

    console.log(unaVar);
}

Continúa en Parte 2: funciones


  • http://twitter.com/MatiasArriola matias-a

    Piola el artículo!

    Un ‘truco’ muchas veces usado para simular un bloque y lograr un scope distinto dentro de las funciones es declarar funciones que se ejecuten instantaneamente..:

    function tipicaFuncionInutil(){
        var a = 100;
        (function(){
            var a = 200;
         })();
        console.log(a); //100
    }
    

    Parece que no. Pero muchas veces es útil!

  • Pingback: » Alcance de Variables – Parte 2: funciones fernetjs

  • Pingback: Valores falsos y verdaderos: || y && | fernetjs

  • Camilo Sosa

    Claro por que serian funciones distintas y no tendría el alcance que se supone debe tener dentro de esa función.