Reputation: 81711
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 :(
Upvotes: 69
Views: 37303
Reputation: 186562
Any function call in ECMAScript ( core language that JS is based on ) produces a separate execution context, which run 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:
Upvotes: 21
Reputation: 36580
The scope chain is used to resolve the value of variable names in javascript. Without a scope chain the Javascript engine wouldn't know which value to pick for a certain variable name if there are multiple defined at different scopes. Scope chain in javascript is lexically defined, which means that we can see what the scope chain will be by looking at the code.
At the top of the scope chain is the global scope, which is the window
object in the browser (global
in NodeJS
). Besides from the global scope, functions have their own scoping of variables. The scope chain can be determined by looking at where functions are defined.
When resolving a variable, inner functions first look at their own scope. If the variable cannot be found in its own scope it will climb up the scope chain and looks for the variable name in the environment where the function was defined. This look like this:
So in our image example when innerFoo
uses the variable bar
it first tries to find it within the scope of the innerFoo (code within function body). Then when it doesn't find it here it climbs up the scope chain to foo
. In foo
there is also no variable which is named bar
. Therefore, it will climb up the scope chain and now look in the global scope. In the global scope is a variable named bar with a value of 10 to which bar
will be resolved.
let foo = 1;
let bar = 1;
function test (bar) {
return function innerTestFunc () {
let foo = 10;
console.log(foo, bar);
}
}
const innerTestFunc1 = test(5);
const innerTestFunc2 = test(20);
innerTestFunc1(); // logs 10, 5
innerTestFunc2(); // logs 10, 20
In the above example we have a function which returns a function. We first store this function in the variables innerTestFunc1
and innerTestFunc2
. This creates a closure which is basically a snapshot of the scope chain of the outer environment.
Then when the functions are executed the function requires a value for both the variables foo
and bar
. The value of foo can be resolved at the level of the innerTestFunc
and is 10 for both. 10 is already found in innerFoo
, so no need to climb the scope chain for foo.
In the case of the bar
variable the function cannot find it in the innerFoo
. Therefore, it will climb up the scope chain. It first encounters the variable bar
in the function test
, therefore it will resolve value of bar
to whatever the value is in the test function (5, 20 in our example).
Upvotes: 6
Reputation: 397
Scope chain in Javascript explained in layman terms
Alex is a happy guy,One fine day,walking down the road with his monthly salary in hand gets mugged.
Later he realizes that tomorrow is the last day to pay for his daughters tuition of 1000$.
He runs home,finds his savings of 400$,worries about the rest(600$).The immediate thought that flashes,is to borrow some from his father Mathew.
Mathew,the poor carpenter,devoid from any money sells his inherited bracelet for 300$ and lends it to his son Alex.
Alex having a good reputation in the society,gets the remaining 300$ from a local bank immediately and pays his daughter tuition on time.
Coming back to Scope chain in Javascript:
Alex-A function in javascript
Mathew-The immediate function,Alex is nested in.
Mathews parents-The immediate function Mathew is nested in.
Bank-Global variables.
function Bank() {
loan=300;
Mathew();
function Mathew() {
mathew=300;
Alex();
function Alex() {
savings:400;
alert('I need some money');
}
}
}
Bank();
Scope chain of Alex at this point looks like: [savings:400]+[mathew:300]+[loan:300];
Upvotes: 4
Reputation: 994
I know it's an old post but it is still helpful for developers. I wanted to do it little different way as it would be more friendly for beginners to understand scope chaining. Here is my modified version of code:
var currentScope = 0; // global scope
function a () {
var currentScope = 1, one = 'scope1';
alert(currentScope);
function b () {
var currentScope = 2, two = 'scope2';
alert(currentScope);
function c () {
var currentScope = 3, three = 'scope3';
alert(currentScope);
alert(one + two + three); // climb up the scope chain to get one and two
}
c();
}
b();
}
a();
Upvotes: 6
Reputation: 827256
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:
Upvotes: 74
Reputation: 30073
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
Upvotes: 5