15 September 2009 ~ 5 Comments

Understanding JavaScript scope and finally ExtJs scope

Simple start

This post starts out with clearifying how scope works in JavaScript, some common mistakes and how to think about scope. As usual, the post is inspired by my own struggeling.

Take the following:

var sampleData=[1,2,3,4,5,6];

function writeSampleData() {
    for(i=0; i<sampleData.length; i++) {
        document.write("1."+i+", ");
    }
}

writeSampleData();

Isolated this works fine. The above will, as expected, output:

1.0, 1.1, 1.2, 1.3, 1.4, 1.5,

Notice how sampleData, defined in the global scope, is available from within the function.

Complicating stuff a bit

var sampleData=[1,2,3,4,5,6];

function writeSampleData() {
    for(i=0; i<sampleData.length; i++) {
        document.write("1."+i+": ");
        document.write(returnSomething(i)+"
");
    }
}

function returnSomething(number) {
    for(i=0; i<3; i++) {
        // Do something here
    }
}

writeSampleData();

Uups! Sorry about that. If you tried running the example code your browser probably froze. Maybe I should mark it with “do not try this at home”…

The very simple point here is the two for loops. They both use the variable i. A variable that has not been explicit defined in the global scope. So, when the writeSampleData() function starts looping it defines a variable in the global scope with the name i. The returnSomething() function is called within the loop. And, returnSomething() has it’s own for loop. A for loop that looks pretty much the same as the one in writeSampleData()! It uses the global variable i. The problem is, it ends at the value 2. Which means, whatever happens – i will never become greater than 2, and the for loop in writeSampleData() will never end because i is set to 2 again and again and again… (that’s why your browser crashed ;-) )

You got the point. Let’s solve this and move on:

var sampleData=[1,2,3,4,5,6];

function writeSampleData() {
    for(var i=0; i<sampleData.length; i++) {
        document.write("1."+i+", ");
        document.write(returnSomething(i)+"
");
    }
}

function returnSomething(number) {
    for(var i=0; i<3; i++) {
        // Do something here
    }
    return i;
}

writeSampleData();

And the learning is:
- Local variables is defined with the “var keyword, if you are within a local scope, for example a function.
- Supress the “var” keyword, and you have a global variable.
- Global variables can be accessed from within any method.

Scope within objects

Lets make an object (yeah yeah, I know – it’s actually not very much more than a regular javascript function)

	function myObject()	{
		this.firsname  = null;
		this.lastname  = null;

		this.setName = function(_first, _last)	{
			this.firstname = _first;
			this.lastname = _last;
		};

		this.alertFirstName = function()	{
			alert("My first name is: "+this.firstname);
		};

		this.alertLastName = function()	{
			alert("My last name is: "+this.lastname);
		};
	}

	obj = new myObject();
	obj.setName("Nils-Fredrik G.", "Kaland");
	obj.alertFirstName();
	obj.alertLastName();

Quite nice. Introducing the “this” keyword. Since we are now working with objects, “this” refers to something that belongs to an instance of the object. This little object works as expected. First, we create the blueprint for an object called myObject. In myObject we define two variables: firstname and lastname and 3 methods: setName(), alertFirstName() and alertLastName(). On line 19 we create an instance of the object, call the setName() and the alert methods.

Let’s complicate this and introduce some errors to explain:

Changing line 03, 05 and 15:

       var lastname = null;
       // ..
       lastname = last;
       // ...
       alert("My last name is: "+lastname);

What will happen now? Try running it!

Hmm… it looks exactly the same. let’s try something else. Add this to the end:

	alert(obj.firstname);
	alert(obj.lastname);

The first one works perfect. The last one does not. It gives you an undefined error. This might be a bit confusing, but I’ll try to clear things up:

- this.variablename means that the object has a variable (or function or object etc etc) that can be accessed from wherever.
- Using the “var” keyword in the object means that the variable is available from within the object. Consider it a private variable.

You get it? No? Read again. Try again. Code again. Now you can continue.

Scope in ExtJs

Let’s put this in an ExtJs context. I struggeled some time to get the hang on the scope stuff in ExtJs. Mainly because I didn’t have the basic knowledge that you now have (if not, read from top again).

	var outsideExt = "I am defined outside Ext.onReady";
	Ext.onReady(function()	{
		this.testvar = "Test1";
		var testvar2 = "Test2";
		cmp = Ext.get(document.body);
		// lets add a listener to the examplediv
		cmp.addListener("click", function(event, htmlElement, options)	{
			// What scope are we in now?
			// Let's try stuff from the examples above:
			alert(this.testvar);
			alert(testvar2);
			alert(outsideExt);
		});
	});

First you get an undefined, then “Test2″ is alerted. This, hopefully, is obvious.

Ext.onReady(function() {
    this.testvar = "Test1";
    var testvar2 = "Test2";
});

Ext.onReady takes a function as a parameter. A function. Not a function blueprint or an object. There is no object present and use of this is worthless.

But, the interesting part here is how testvar2 is available from all methods within Ext.onReady.

ExtJs Scope – summary

While working with ExtJs things have a tendency to get complicated. I tend to end up with lot’s of different data stores, handlers, objects and components. Understandig how scope works is important, or you’ll soon end up rewriting and restructuring your code. And, it is simple.

I should probably follow up this with a post about Ext namespacing….?

Further reading

Professional JavaScript Frameworks: Prototype,YUI, ExtJS, Dojo and MooTools
Beginning PHP RIA Using Extjs
Zend Studio for Eclipse Developer's Guide

5 Responses to “Understanding JavaScript scope and finally ExtJs scope”

  1. Dave Smith 21 October 2009 at 01:06 Permalink

    After reading dozens of articles on this subject, I finally found the man who knows how to write!

    Hope you continue to share your wisdom in such a clear and accessible format.

  2. Nils-Fredrik G. Kaland 21 October 2009 at 02:50 Permalink

    Dave Smith,
    thanks for you very nice feedback!

    Out of curiosity, what was clearifing for you? The part about how to think about scope in extjs or the general javascript part?

    Best regards,
    Nils-Fredrik

  3. Dave Smith 5 November 2009 at 05:57 Permalink

    I found the part covering scope in extjs to be the most valuable.

    The forum post http://www.extjs.com/forum/showthread.php?t=6336 was quite helpful, as Jozef Sakalos is an excellent writer. But it still left me unable to directly apply my understanding to every occurrence when writing my own code.

    After working with your examples, everything clicked right into place and I knew I had mastered the topic.

    Thanks again for helping.

  4. Hari 28 November 2014 at 09:10 Permalink

    After spending so many cycles ,,,, finally I got it !!
    Thanks!!
    This guy ‘scope’ has wasted my time :-/ ;)

    Thanks
    ~Hari


Leave a Reply