Javascript Scope Gotcha

I just learned something very surprising about scope in Javascript from John Resig. Take a look at this very simple example:

Scope of Object Properties


var aObj, bObj;
var val = 'c';

function a() {
this.val = 'a';
}
a();

function b() {
this.val = 'b';
}
b();

bObj = new b();
aObj = new a();

console.log(aObj.val, bObj.val, val);

What output would you expect to find in the Javascript console? I thought I’d see a b c. Not so. The output is actually a b b. The implication of this is that properties defined within the context of functions (which are objects in Javascript) are actually placed in the global scope at the time the functions are called as well as locally in each function.

The danger in this behaviour is that an unaware programmer could rely on the global variable val defined at the beginning of the script without realizing that it has ultimately been hidden by b.val. This could lead to some serious head-scratching since it isn’t at all the behaviour I would have assumed.

How can we avoid the problem? Try this:

Revised Code


var aObj, bObj;
var val = 'c';

function a() {
var val = 'a';
this.getVal = function() {
return val;
}
}
a();

function b() {
var val = 'b';
this.getVal = function() {
return val;
}
}
b();

bObj = new b();
aObj = new a();

console.log(aObj.getVal(), bObj.getVal(), val, aObj.val, bObj.val);

This revised code outputs a b c undefined undefined. For the uninitiated, the above code uses closures to create real local variables. Another fix would be to avoid name collisions on variables you intend to be local to the functions a() and b(), but this is an inferior approach since errors will easily be introduced whenever the code is revised.

For a straight-forward explanation of closures, please try javascriptkit.com’s explanation of them. If you have any questions, please feel free to leave them in the comments.

Advertisements

About Fergus

Fergus likes to invent cool titles for himself, such as “Communications Specialist” or “Internet Architect”. What it really comes down to is that Fergus’s passion is internet communication. He believes that helping people communicate more effectively makes the world a better place. To this end, he seeks opportunities to help individuals, businesses, and non-profits to communicate their ideas, products, and services beautifully. Some examples of the types of work Fergus undertakes: web design, graphic design, programming, and search-engine optimization. Fergus also enjoys consulting with people about their existing web sites and strategies as well as their plans. Fergus doesn’t enjoy writing about himself in the third-person quite as much, but sometimes it seems a necessary evil.
This entry was posted in Programming, Web and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s