¿Por qué la variable sombreada se evalúa como indefinida cuando se define en un ámbito externo?

4 minutos de lectura

¿Por que la variable sombreada se evalua como indefinida cuando
PlayaCorredorFred

Considere la siguiente pieza de código:

<html><head></head>
<body>
    <script type="text/javascript">
        var outside_scope = "outside scope";
        function f1() {
            alert(outside_scope) ;
        }
        f1();
    </script>
</body>
</html> 

El resultado de este código es que el cuadro de alerta muestra el mensaje “fuera del alcance”. Pero, si modifico ligeramente el código como:

<html><head></head>
<body>
    <script type="text/javascript">
        var outside_scope = "outside scope";
        function f1() {
            alert(outside_scope) ;
            var outside_scope = "inside scope";
        }
        f1();
    </script>
</body>
</html> 

el cuadro de alerta muestra el mensaje “indefinido“. Podría haber entendido la lógica si muestra “indefinido” en ambos casos. Pero eso no está sucediendo. Muestra “indefinido” solo en el segundo caso. ¿Por qué es esto?

¡Gracias de antemano por tu ayuda!

Las variables están sujetas a elevación. Esto significa que, independientemente de dónde se coloque una variable dentro de una función, se mueve a la parte superior del ámbito en el que se define.

Por ejemplo:

var outside_scope = "outside scope";
function f1() {
    alert(outside_scope) ;
    var outside_scope = "inside scope";
}
f1();

Se interpreta en:

var outside_scope = "outside scope";
function f1() {
    var outside_scope; // is undefined
    alert(outside_scope) ;
    outside_scope = "inside scope";
}
f1();

Por eso, y por el único alcance de función que tiene JavaScript, se recomienda declarar todas las variables al mismo tiempo. parte superior de la función, para parecerse a lo que sucederá.

  • después de años no sabía eso, quizás porque siempre declaro en la parte superior, como en C.

    – Vitim.es

    18 dic. 11 a las 22:13

En el primer caso, su código accede a la variable global “outside_scope”, que se ha inicializado como “fuera del alcance”.

Javascript tiene un alcance de nivel de función, por lo que en el segundo caso está accediendo a la variable de alcance de función “outside_scope”, pero aún no se ha inicializado en el momento del cuadro de alerta. Entonces se muestra indefinido.

JavaScript tiene alcance de función, no alcance de bloque.

En el segundo caso, la declaración de outside_scope se eleva a la parte superior de la función (pero la asignación no).

Este es un gran ejemplo de por qué el código JavaScript es más fácil de leer si coloca todas sus declaraciones de variables en la parte superior de la función. Su segundo ejemplo es equivalente a:

function f1() {
    var outside_scope;
    alert(outside_scope);
    outside_scope = "inside scope";
}

y probablemente ahora pueda entender por qué se está volviendo “indefinido”.

En el segundo ejemplo, la variable local existe para todo el alcance de la función. No importa que lo haya definido después de la alerta, existe para toda la función.

Sin embargo, la asignación real no ocurre hasta después de la alerta, de ahí el “indefinido”.

Esto se debe a algo llamado levantamiento de declaraciones de variables.

Básicamente, JavaScript separa una declaración de variable en dos, dejando la tarea donde hiciste la declaración y elevando la declaración real a la parte superior de la función:

var f1 = function ()  {
   // some code
   var counter = 0;
   // some more code
}

var f2 = function () {
   var counter; // initialized with undefined
   // some code
   counter = 0;
   // some more code
}

En tiempo de ejecución, f1() se traduce en f2(). Escribí una publicación de blog detallada sobre esto aquí. Espero que esto te ayude a entender lo que sucede en tu código.

Esta es también la razón, es recomendado para declarar sus variables en la parte superior de una función en JavaScript. Le ayuda a comprender lo que hace el código, cuando se ejecuta.

¿Por que la variable sombreada se evalua como indefinida cuando
pstantón

ese es un caso interesante.

en el primer ejemplo, ha definido una variable ‘global’. tiene alcance global y por lo tanto es accesible en cualquier función/objeto para la ejecución.

en el segundo ejemplo, ha ‘bloqueado’ la variable global con la variable de alcance de la función, pero como aún no se ha inicializado en el momento de la alerta, devuelve ‘indefinido’.

Estoy de acuerdo en que esta no es la peculiaridad más intuitiva, pero tiene sentido.

.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad