简体   繁体   中英

Trying to figure out how scope works

I'm trying to learn JS on codeacademy and I can't understand/get past this thing. Can someone please provide an answer and also an explanation of why is it so? Would deeply appreciate.

// This function tries to set foo to be the
// value specified.

function setFoo(val) {
  // foo is declared 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);

You can see scope as a term meaning what variables you can reach at a specific "level" in the code. In JavaScript, these "levels" are defined by functions. Each function introduces a new level.

For example, take this sample code:

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
  }
}

So in your case, you should declare var foo; outside the function, preferably above it. Then you can set it inside setFoo with foo = val; . foo then refers to the one you declared in the level above setFoo .

foo is accessible both in setFoo and in the alert call that way; compare it with the above sample code ( function1 is setFoo , a is foo and the alert call is in the top-most level. function2 , b and c are not used in your case.).

// Create globale variable
// (You should not use globale variables!)
var foo;

// set value
function setFoo(val) {
  foo = val;
}
setFoo(10);

// show value
alert(foo);

Just declare foo outside any function then it will be global:

var foo = null;

function setFoo(val) {
  foo = val;
}

setFoo(10);

alert(foo);

Try it !

When you declare a variable in Javascript it is only visible to code that is in the same function as it is declared, or a function inernal to that function. Because foo is originally declared in the SetFoo function nothing outside of SetFoo is able to see it, so the call to alert fails as foo does not exist in the gloabl scope.

As the comments suggest, moving the declaration of foo out of the function and into the global scope (which you can think of as a catch-all function that contains everything) would allow you to use foo when calling alert.

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

Every function in Javascript has it's own scope. That means that every variable you define there with the var keyword, will only be available within that function. That means that when you call setFoo(10) , you create the variable foo, give it a value of five, after which it is immediately destroyed because it went out of scope.

There are multiple ways to solve this problem. The first would be to remove the var keyword. This would put foo in the global scope, which means that it's available everywhere. However, this is discouraged, you want to keep the global scope as uncluttered as possible, so that if you have javascript code provided by multiple people on the same page, they can't overwrite other people's variables. Another way to do it would be this:

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

In this example, the only thing you're putting in the global scope is the alertfoo function, because you want that to be available everywhere. The alertfoo function is defined inside the setFoo function, this means that although foo should have gone out of scope after setfoo has been executed, it is kept in memory, because alertfoo has access to it.

This makes for some nice tricks. For example, let's say you're making a javascript library that will be included on other people's pages, you'll want to create a scope inside of which you can define variables, without polluting the global scope. The most common way to do this, is by declairing a self-executing function. This is a function which is executed immediately after being defined, it looks like this:

(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;}
})();

You can make this even better by making only one object global, and provide your interfae through the methods of that object, this way, you create a namespace with all the functions that your library contains. The next example uses an object literal to do this. In javascript, you can create an object by putting key/value pairs petween curly braces. the key/value pairs are properties of the object. for example:

(function(){
    var privatevar = 10,otherprivate=20;

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

Original code:

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

setFoo(10);

alert(foo); // Crash!

Their advice to fix the crash:

Fix this by moving the declaration of foo outside of the function

I'm guessing you're confused as to what they mean by "outside of the function".

Try this edited code:

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"

Variables defined in the function is valid only in the function

function setFoo(val) {
    foo = val;
}

在JavaScript中,新范围仅由函数创建

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM