tags:

views:

5949

answers:

6

What is the scope of variables in javascript? Do they have the same scope inside as opposed to outside a function? Or does it even matter? Also, where are the variables stored if they are defined globally?

+4  A: 

Variables declared globally have a global scope. Variables declared within a function are scoped to that function, and shadow global variables of the same name. This tutorial page has lots of good examples.

(I'm sure there are many subtleties that real JavaScript programmers will be able to point out in other answers. In particular I came across this page about what exactly this means at any time. Hopefully the first link is enough to get you started though.)

Jon Skeet
I'm afraid to even begin answering this question. As a Real Javascript Programmer, I know how quickly the answer could get out of hand. Nice articles.
Triptych
@Triptych: I know what you mean about things getting out of hand, but *please* add an answer anyway. I got the above just from doing a couple of searches... an answer written by someone with actual experience is *bound* to be better. Please correct any of my answer which is definitely wrong though!
Jon Skeet
+9  A: 

Javascript uses scope chains to establish the scope for a given function. There is typically one global scope, and each function defined has its own nested scope. Any function defined within another function has a local scope which is linked to the outer function. It's always the position in the source that defines the scope.

An element in the scope chain is basically a Map with a pointer to it's parent scope.

When resolving a variable, javascript starts at the innermost scope and searches outwards.

krosenvold
+1 for explaining scope chains.
Török Gábor
A: 

Ok, understood (should have been obvious) but if the variable is defined globally, where is it stored meaning where does it's scope chain lead/start?

lYriCAlsSH
starts with: window
geowa4
starts with window IN WEB BROWSERS. Javascript as a language technically runs within a "host" object, and that's where global variables are stored. This varies by application.
Triptych
This is not an answer but a separate question.
Török Gábor
You can get at the global scope in any implementation by running a closure like this in the global scope: `(function(global) { /* Anything in the global scope can be found at global.varName */ })(this);`
eyelidlessness
+1  A: 

Here's an example:

<script>

var globalVariable = 7; //==window.globalVariable

function aGlobal( param ) { //==window.aGlobal(); 
                            //param is only accessible in this function
  var scopedToFunction = {
    //can't be accessed outside of this function

    nested : 3 //accessible by: scopedToFunction.nested
  };

  anotherGlobal = {
    //global because there's no `var`
  }; 

}

</script>

You'll want to investigate closures, and how to use them to make private members.

geowa4
+38  A: 

I think about the best I can do is give you a bunch of examples to study. Javascript programmers are practically ranked by how well they understand scope. It can at times be quite counter-intuitive.

// a globally-scoped variable
var a=1;

// global scope
function one(){
    alert(a); 
}

// local scope
function two(a){
    alert(a);
}

// local scope again
function three(){
  var a = 3;
  alert(a);
}

// Intermediate: no such thing as block scope in javascript
function four(){
    if(true){
        var a=4;
    }

    alert(a); // alerts '4', not the global value of '1'
}


// Intermediate: object properties
function Five(){
    this.a = 5;
}


// Advanced: closure
var six = function(){
    var foo = 6;

    return function(){
        // javascript "closure" means I have access to foo in here, 
        // because it is defined in the function in which I was defined.
        alert(foo);
    }
}()


// Advanced: prototype-based scope resolution
function Seven(){
  this.a = 7;
}

// [object].prototype.property loses to [object].property in the scope chain
Seven.prototype.a = -1; // won't get reached, because 'a' is set in the constructor above.
Seven.prototype.b = 8; // Will get reached, even though 'b' is NOT set in the constructor.



// These will print 1-8
one();
two(2);
three();
four();
alert(new Five().a);
six();
alert(new Seven().a);
alert(new Seven().b);
Triptych
wow thanks, very comprehensive. Although i didn't know about the last bit about closure.
lYriCAlsSH
Not even close to being comprehensive, but this is maybe the must-know set of Javascript scope tricks one needs to effectively even READ modern javascript.
Triptych
Considering your remark on 'ranking', i guess i'll start reading more on this sort of thing. But its not as bad as i thought, i understood the logic behind it rather well. Although, about the object properties, if i declare it globally will it be referenced by object.prototype?
lYriCAlsSH
+3  A: 

In "Javascript 1.7" (Mozilla's extension to Javascript) one can also declare block-scope variables with let statement:

 var a = 4;
 let (a = 3) {
   alert(a); // 3
 }
 alert(a);   // 4
KennyTM