views:

645

answers:

4

Hi,

I've reading scope chain in Javascript but it didn't make any sense to me, could any one tell me what is scope chain and how it works with a graphic or something even an idiot can understand. I googled it but I didn't find something comprehensible :(

Thanks in advance.

+3  A: 

This is about closure. You may use variables outer from scope in the inner scope:

function get_inner_scope () {
    var outer = 'Outer variable value';
    return function () {
        alert(outer);
    }
}
f = get_inner_scope();
f(); // alerts Outer variable value

More deatailed info with other samples by first google's link: http://blogs.msdn.com/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx

Anatoliy
+4  A: 

Any function in ECMAScript ( core language that JS is based on ) is a separate execution context, and runs individually from one another. Inside of each execution context, this refers to the object in question, defaulting to whatever the function is attached to.

function foo() {
    alert(this===window)
}

Would alert true, because the window is the object which owns the 'foo' method. Any variables defined in a function become accessed through that function's unique scope chain, environment.

function world() {
    var name = 'global';
    alert(name)
}

would alert 'global' obviously.

function world() {
    var name = 'global';
    (function() {
        var name = 'country';
        alert(name)
    })();
    alert(name)
}

In the latest example, when the first alert is invoked, Javascript determines that in the scope chain of the inner function that the identifier name is defined, so it doesn't have to look up the scope chain to grab it.

In the second alert invocation, name is also defined in the same context and alerts 'global';

function world() {
    var name = 'global';
    (function() { alert(name) })();
}

In this example, the name identifier is not defined in the same context and thus it has to travel up the scope chain to the outer function where name is defined, and it alerts global.

Reference:

meder
+3  A: 

To understand the scope chain you must know how closures work.

A closure is formed when you nest functions, inner functions can refer to the variables present in their outer enclosing functions even after their parent functions have already executed.

JavaScript resolves identifiers within a particular context by traversing up the scope chain, moving from locally to globally.

Consider this example with three nested functions:

var currentScope = 0; // global scope
(function () {
  var currentScope = 1, one = 'scope1';
  alert(currentScope);
  (function () {
    var currentScope = 2, two = 'scope2';
    alert(currentScope);
    (function () {
      var currentScope = 3, three = 'scope3';
      alert(currentScope);
      alert(one + two + three); // climb up the scope chain to get one and two
    }());
  }());
}());

Recommended reads:

CMS
So, currentScope 3 will override the currentScope 1 value ?
Braveyard
@Aaron Not override, but **shadow**.
kangax
@Aaron, exactly as @kangax says, within the scope of the *third* function the `currentScope` variables declared on the *second, first and global* scopes will be simply *shadowed* or *hidden*, their value will remain intact on the outer closures, since in the third function, you are declaring a **new** `currentScope` variable that resides in that scope, and for that when you access it there, it will be the first at the scope chain.
CMS
But what if I want to access scopeChain in the second function then will it be 3 since the place where variables defined rather than place the variables get executed ?
Braveyard
I think I got it, It is different than what I thought before.Let me tell you what I understood : every variables gets the value actually from where it is defined rather than executed so the functions have their own scope and e.g. currentScope 3 hides the value of currentScope 2 because they are defined in different scopes but if I want to access currentScope in the second functions it would return 2 because currentScope 3 is only effective in third function, it only effects the variables defined in its own scope. That makes sense now. So if I don't use var, then I happen to define a global one
Braveyard
And I actually run your code here and it showed me the right thing : http://jsbin.com/afebi/edit thanks.....
Braveyard
And by doing that, I hide my variables which means they are like private variables in C#.
Braveyard
@Aaron, a better example on C# would be name hiding through nesting (http://is.gd/3JUQs) or through inheritance (http://is.gd/3JUVr)
CMS
A: 

Some good examples of Javascript scope chain can be found here http://zhapu-road.appspot.com/2010/07/30/Javascript-scope-chain-example.html

ValidfroM