i am dustin diaz

a JavaScriptr...

boosh.

don't worry about it.

Scoping anonymous functions

This is obviously a no-brainer in that knowing something like this works in JavaScript, but it never really occurred to me to even do such a thing until today. Take the following example which 'calls' the anonymous function within a unique scope:

Scoping anonymous funcitons

var o = 'hello world';



(function() {

  alert(this);

}).call(o);
It seems ridiculous (in a good way), but it works!

So what's this mean?

It's actually a big deal. Think about how many times you've lost your desired scope due to being inside the scope of another function. Confused? How many times have you done the following:

Pitfalls anonymous functions

// timeout functions

function Constructor() {

  this.foo = 'bar';

  var that = this;

  this.timerId = window.setTimeout(function() {

    alert(that.foo);

  }, 10000);

}



// local functions

Constructor.prototype.getFoo = function() {

  var that = this;

  var getInternalFoo = function() {

    return DED.isString(that.foo) ? that.foo : 'new foo';

  }();

};
Ok, still not a huge deal, but we can clean up the code a bit, and I would sway from using this on non-anonymous functions where scope should be explicitly defined by the author. Here's how we can rewrite the code above without using the silly old this = that convention.

Rewritten with proper scope



// local functions

Constructor.prototype.getFoo = function() {

  var getInternalFoo = function() {

    return (DED.isString(this.foo) ? this.foo : 'new foo';

  }.call(this);

};

Ok, what about function callbacks that need scope inducing

(Hehe. Scope inducing, that sounds funny... (anyway)) As you noticed above in the first example with the setTimeout, the first argument takes in a function callback which is different than simply immediately invoking a function. Funny enough, the work around for this is to.... (yeah you guessed it), add another closure! Note the two following snippets of code. The first immediately executes and alerts "hello world", the second waits for five seconds, and does likewise:

Scoping it up

var o = 'hello world';



// first snippet

(function() {

  alert(this);

}).call(o);



// second snippet

window.setTimeout(function() {

  (function() {

    alert(this);

  }).call(o); 

}, 5000);

Pretty fun, huh? Yeah, I thought so too. Cheers.

this is who i am

Hi, my name is Dustin Diaz and I'm an Engineer @ObviousCorp. Previously @Twitter, @Google, and @Yahoo, author of Strobist® Info co-author of JavaScript Design Patterns, co-creator of the Ender JavaScript Framework, a Photographer, and an amateur Mixologist. This is my website. Welcome!

On this site I write about JavaScript. You can also follow along with my open-source work on Github.

This site is optimized and works best in Microsoft Internet Explorer 6.