¿Las variables son estática o dinámicamente "scoped" en javascript?


O más específico para lo que necesito:

Si llamo a una función desde dentro de otra función, ¿va a extraer la variable desde dentro de la función que llama, o desde el nivel anterior? Ex:

myVar=0;

function runMe(){
    myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

¿Qué termina siendo myVar si callMe() se llama a través de runMe()?

Author: kylex, 2009-06-06

7 answers

Jeff tiene razón. Tenga en cuenta que esto no es realmente una buena prueba de alcance estático (que JS tiene). Mejor sería:

myVar=0;

function runMe(){
    var myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

runMe();
alert(addMe);
alert(myVar);

En un lenguaje de alcance estático (como JS), que alerta 10 y 0. La var myVar (variable local) en runMe sombrea la MiVar global en esa función. Sin embargo, no tiene ningún efecto en callMe, por lo que callMe utiliza el MiVar global que todavía está en 0.

En un lenguaje de ámbito dinámico ( a diferencia de JS), callMe heredaría el ámbito de runMe, por lo que addMe se convertiría en 20. Tenga en cuenta que myVar seguiría siendo 0 en la alerta, porque la alerta no hereda el ámbito de ninguna de las funciones.

 43
Author: Matthew Flaschen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-09 17:43:00

Si tu siguiente línea es callMe();, entonces addMe será 10, y myVar será 0.

Si tu siguiente línea es runMe();, entonces addMe será 20, y myVar será 10.

Perdóname por preguntar - ¿qué tiene esto que ver con el enlace estático/dinámico? ¿No es myVar simplemente una variable global, y el código de procedimiento (desenvolver todo en la pila de llamadas) no determinará los valores?

 4
Author: Jeff Meatball Yang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-06 04:21:49

Las variables tienen un alcance estático en JavaScript (el alcance dinámico es realmente un negocio bastante desordenado: puede leer más al respecto en Wikipedia).

En su caso, sin embargo, está utilizando una variable global, por lo que todas las funciones accederán a esa misma variable. La respuesta de Matthew Flaschen muestra cómo se puede cambiar para que el segundo míVar sea en realidad una variable diferente.

Esta página explica cómo declarar variables globales vs. locales en JavaScript, en caso de que no estés demasiado estoy familiarizado con él. Es diferente de la forma en que la mayoría de los lenguajes de scripting lo hacen. (En resumen: la palabra clave" var " hace que una variable sea local si se declara dentro de una función, de lo contrario la variable es global.)

 3
Author: xyz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-06 05:38:58

A menos que utilice la palabra clave var para definir sus variables, todo termina siendo una propiedad en el objeto window. Así que su código sería equivalente a lo siguiente:

window.myVar=0;

function runMe(){
    window.myVar = 10;
    window.callMe();
}

function callMe(){
   window.addMe = window.myVar+10;
}

Si tienes esto en mente, siempre debe estar claro lo que está sucediendo.

 1
Author: Tobias Cohen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-20 12:54:02

Hasta donde yo entiendo, cualquier variable sin la palabra clave var se trata global , con ella, su ámbito local, así que:

// This is a local scoped variable.
var local_var = "something"; 

// This is a global scoped variable.
global_var = "something_else";

Como una buena práctica de JS, se recomienda agregar SIEMPRE la palabra clave var.

 0
Author: jimx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-06 06:07:59

Me gustaría añadir que las expresiones lambda también tienen un alcance estático en la ubicación en la que se define la expresión. Por ejemplo,

var myVar = 0;

function foo() {
    var myVar = 10;
    return { bar: function() { addMe = myVar + 10; }}
}

var myObj = foo();

var addMe = 6;
alert(addMe);

myVar = 42;
myObj.bar();

alert(addMe);

Esto mostrará 6 y 20.

 0
Author: John Henckel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-08 19:09:13
myVar=0;

function runMe(){
    myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

En lo que respecta a la salida , myVar y addMe serán variables globales en este caso, como en javascript, si no declaras una variable con var, entonces implícitamente la declara como global, por lo tanto, cuando llamas a runMe (), entonces myVar tendrá el valor 10 y addMe tendrá 20 .

 0
Author: Vikash Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-01 21:54:13