Tratando de descubrir cómo funciona el scope

Estoy tratando de aprender JS en codeacademy y no puedo entender / superar esta cosa. ¿Puede alguien dar una respuesta y también una explicación de por qué es así? Lo agradecería profundamente

// This function tries to set foo to be the // value specified. function setFoo(val) { // foo is declanetworking in a function. It is not // accessible outside of the function. var foo = val; } setFoo(10); // Now that we are outside the function, foo is // not defined and the program will crash! Fix this // by moving the declaration of foo outside of the // function. Make sure that setFoo will still update // the value of foo. alert(foo); 

Puede ver el scope como un término que significa qué variables puede alcanzar a un "nivel" específico en el código. En JavaScript, estos "niveles" están definidos por funciones. Cada function introduce un nuevo nivel.

Por ejemplo, tome este código de muestra:

 var a; // you can access a at this level function function1() { var b; // you can access a, b at this level function function2() { var c; // you can access a, b, c at this level } } 

Entonces en tu caso, debes declarar var foo; fuera de la function, preferiblemente por encima de ella. Luego puede configurarlo dentro de setFoo con foo = val; . foo se refiere a la que declaraste en el nivel de setFoo anterior.

foo es accesible tanto en setFoo como en la llamada de alert ; compárelo con el código de ejemplo anterior ( setFoo es setFoo , a es foo y la llamada de alert está en el nivel más alto. function2 , b no se usan en su caso).

 // Create globale variable // (You should not use globale variables!) var foo; // set value function setFoo(val) { foo = val; } setFoo(10); // show value alert(foo); 

Simplemente declara foo fuera de cualquier function, entonces será global:

 var foo = null; function setFoo(val) { foo = val; } setFoo(10); alert(foo); 

Intentalo !

Cuando declara una variable en Javascript, solo es visible para el código que está en la misma function que se declara, o una function inernal a esa function. Como foo se declaró originalmente en la function SetFoo, nada fuera de SetFoo puede verlo, por lo que la llamada a la alerta falla ya que foo no existe en el scope global.

Como sugieren los comentarios, mover la statement de foo fuera de la function y dentro del scope global (que se puede considerar como una function global que lo contiene todo) le permitiría usar foo cuando llame alerta.

 var foo; function setFoo(val) { foo = val; } setFoo(10); alert(foo); // No longer crashes 

Cada function en Javascript tiene su propio scope. Eso significa que cada variable que definas allí con la palabra key var, solo estará disponible dentro de esa function. Eso significa que cuando llamas a setFoo(10) , creas la variable foo, le das un valor de cinco, después de lo cual se destruye inmediatamente porque salió del scope.

Hay varias forms de resolver este problema. El primero sería eliminar la palabra key var. Esto pondría a foo en el scope global, lo que significa que está disponible en todas partes. Sin embargo, esto se desaconseja, usted quiere mantener el scope global lo más orderado posible, de modo que si tiene código de JavaScript proporcionado por varias personas en la misma página, no pueden sobrescribir las variables de otras personas. Otra forma de hacerlo sería esto:

 function setFoo(val){ var foo = val; alertfoo = function(){ alert(foo) } } 

En este ejemplo, lo único que está poniendo en el ámbito global es la function alertfoo, porque quiere que esté disponible en todas partes. La function alertfoo se define dentro de la function setFoo, esto significa que aunque foo debería haber salido del scope después de que se haya ejecutado setfoo, se mantiene en la memory, porque alertfoo tiene acceso a él.

Esto lo convierte en algunos buenos trucos. Por ejemplo, supongamos que está creando una biblioteca de JavaScript que se includeá en las páginas de otras personas; querrá crear un ámbito dentro del cual pueda definir variables, sin contaminar el scope global. La forma más común de hacerlo es declarando una function autoejecutable. Esta es una function que se ejecuta inmediatamente después de ser definida, se ve así:

 (function(){ //set variables you want to be global in your own code var mainpage = document.getElementById('main'); //define functions you want to make available to other people in a way that puts them in the global scope setMainElement = function(newmain){mainpage = newmain;} })(); 

Puede mejorar esto haciendo que un solo object sea global, y proporcionar su interfaz a través de los methods de ese object, de esta manera, crea un espacio de nombres con todas las funciones que contiene su biblioteca. El siguiente ejemplo usa un object literal para hacer esto. En javascript, puede crear un object colocando pares key / valor entre llaves. los pares key / valor son properties del object. por ejemplo:

 (function(){ var privatevar = 10,otherprivate=20; publicInterface = { 'addToPrivate': function(x){privatevar+=x;}, 'getPrivate': function(){return private} }; })(); 

Código original:

 function setFoo(val) { var foo = val; } setFoo(10); alert(foo); // Crash! 

Su consejo para arreglar el locking:

Arregle esto moviendo la statement de foo fuera de la function

Supongo que estás confundido sobre lo que quieren decir con "fuera de la function".

Pruebe este código editado:

 var foo = 5; // "var" declares the variable to be in this outer scope function setFoo(val) { foo = val; // but we can still access it in this inner scope... } setFoo(10); alert(foo); // Displays a dialog box that says "10" 

Las variables definidas en la function solo son válidas en la function

 function setFoo(val) { foo = val; } 

En JavaScript, los nuevos ámbitos solo se crean con funciones