Tutorial:What is that Scope all about (Legacy)

This version of our Learning Center is unmaintained.
This article may be out-of-date or contain incorrect information.
Please visit the new Sencha Learning Center for up-to-date material.

Go to the new Sencha Learning Center

From Sencha - Learn

Jump to: navigation, search
Summary: This tutorial explains basics of scope and variables visibility in JavaScript.
Author: Jozef Sakalos
Published: August 23, 2007
Ext Version: 1.1+ / 2.0+
Languages: en.png English cn.png Chinese kr.png Korean fr.png French tr.png Turkish it.png Italian de.png German

Contents

Questions/Comments

Want to discuss something in this tutorial? Please see this thread.

Before you start

The best way of studying this tutorial is to have Firefox with Firebug handy. This way you can test the tutorial examples immediately.

Install both of them if you haven't already done so.

Definition

scope
1. (noun) an area in which something acts or operates or has power or control [1]
2. (noun) In programming, the visibility of variables within a program; for example, whether one function can use a variable created in another function. [2]

So what are we going to deal with? We're going to find out if and where a variable is available when we're running functions and what it means when someone says "it's a scope issue" or "it's running in wrong scope" or similar.

Let's go

Each function you define in JavaScript is a method of an object. Even if you write it like this:

function fn() {
    alert(11);
}

He must be kidding, you say. But you can do a very simple demonstration to prove to yourself that this is true. You won't need any javascript files, servers or html for this example. Just open Firefox, then open Firebug's bottom window and click on console tab. Just above status bar of Firefox you can see line starting with >>> where you can type. If you don't see the >>> at the bottom of the console tab, pull down Options and uncheck Larger Command Line. Type there:

function fn() { alert(11); };

and Enter. Nothing happened, yeah? What you've done in fact is that you defined function fn. Now try:

fn();

and Enter. Got alert with 11? So far so good. Now try:

window.fn();
this.fn();

Got the same? It is because the function fn is a method of the window object in fact. The second line gives you proof that the this variable equals to the window object. The fact that you do not need to call all your functions as window.myFunction(...) is only for convenience and to ease the work of lazy programmers.

The window object

The window object is always there--you can think of it as the browser window. It contains all other objects such as the document object and all globally defined variables.

You can open Firebug, switch to Script tab, and type window in the "New watch expression..." box on the right side of Firebug, then hit enter. You can explore the window object to get a clue what's there. Alternatively you can just click on the DOM tab and see the same information about the window object.

Especially, find the fn function we have defined earlier.

Each frame or iframe has its own window object, its own global space.

Understanding scope

Now, let's complicate it a bit. Switch back to Firebug Console tab and type:

o1 = {testvar:22, fun:function() { alert('o1: ' + this.testvar); }};
o2 = {testvar:33, fun:function() { alert('o2: ' + this.testvar); }};

What you've done? You've defined objects o1 and o2 each with same properties and methods but properties hold different values.


Now try:

fun();
window.fun();
this.fun();

Errors, yeah? Sure, object window (which equals to this) doesn't have method fun. Try the following:

o1.fun();
o2.fun();

Got 22 and 33? Very good!

And now the last complication. We have primitive functions here that you wouldn't want to type for each of your objects but, let's say, o1.fun is a very clever and long function you've been developing over the last week and now it finally works. Imagine that it has 100 lines scattered with variable this all over the code. So how would you call (execute) o1.fun but have this point to o2? Try the following:

o1.fun.call(o2);

You see? You have forced variable this to point to o2 while executing the method fun of o1, in other words, more scholarly: the method o1.fun is running in the scope of object o2.

You can think of scope as of value of variable this while running a function, a method of an object.

Visibility of variables

The visibility of variables is closely related to the scope subject. We already know that variables (functions are also variables) defined outside of any object or function are global or, technically, they are properties of the global window object.

Global variables are visible everywhere; inside or outside of all functions. If you modify a global variable value in one function, other functions see the modified value.

We also know that object can have their own properties (such as testvar above) that are visible both from inside and outside of objects. Try:

alert(o1.testvar); // accessing o1 property testvar from outside

Accessing from inside has already been demonstrated in methods fun of both test objects.

The last piece of the puzzle are local variables defined inside of functions with the var keyword:

i = 44; 
function fn2() { 
    var i = 55; 
    alert(i); 
}
fn2();

What will you get? Right, 55. Variable i defined in fn2 is local to the function fn2 and it has nothing to do with global variable i that equals to 44.

But:

alert(i);

will give you 44 as now you're accessing the global variable i.

I hope this sheds some light on the subject of scope and variable visibility.

Further reading:

This page was last modified on 11 August 2010, at 11:58. This page has been accessed 123,565 times.