Achieving Block Scope With Immediate Functions In JavaScript

I was digging around on twitter and I found a great comment from @BenAtExocortex:

“Javascript has no block scope (!) but one can use self-executing functions instead (as Javascript has function scope.)”

What Ben is referring to is that JavaScript doesn’t scope your variables to if statements or other blocks the way C# and other languages would. Consider this example in C#:

public void DoSomething(){
  // c# scopes variable declaration inside of blocks
  if (true){
    int i = 0;
  }
  // this is a compiler error or warning
  i++;
}

On the “i++” line, the C# compiler (or Resharper / Telerik JustCode / etc) would throw a compiler error or warning, telling you that the variable isn’t defined at this point. This happens because the variable declaration is scoped to the if statement.

In JavaScript, though, the same code is perfectly fine:

function doSomething(){
  // javascript scopes variable declaration inside of blocks
  if (true){
    var i = 0;
  }
  // this is perfectly fine, and results in i == 1
  i++;
}

This is because JavaScript scopes your variables to functions and not to if-blocks. But, we can achieve block-like scope through the use of immediate functions like this:

function doSomething(){
  // outer scope variable
  var i = (function(){
    if (true){
      // inner scope variable
      var x = 0;
    }
    x++;
    return x;
  })();
  // the result is i == 1, inside of doSomething's scope
}

The “i” var in the “doSomething” function is assigned the value returned by the immediate function. The “x” var is scoped to the immediate function giving us block-like scope for our variables.

Of course, this does add a bit of noise to our JavaScript. Chances are if you need something like this you’ll really want to extract a proper function. There’s also some memory and performance implications due to re-defining and executing the immediate function every time you run “doSomething”. But, if you understand the implications and you need to achieve block-like scope in your JavaScript to isolate temporary variables, this is one way to do it.


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in Javascript. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://twitter.com/ntcoding Nick

    Would this even be an issue if we followed uncle bob’s rules about methods being short and only doing one thing? Maybe that is that much simpler than defining in-line functions and invoking them?

    I’m no javascript whizz, and I’m not being a troll – genuinely putting a case foward.

    • http://mutedsolutions.com Derick Bailey

      i generally agree and hinted at this in the comments below that last gist. i’m guessing there may be some times when this would be useful, but it would likely be a very narrow and exceptional set of circumstances

  • Julian Birch

    This is even more elegant in CoffeeScript. You just say

    do ->
    Scoped code

    As for Uncle Bob, I’m all for splitting functions into small components, but if they’re not re-used, doesn’t it make sense to simply define them in the master function?

  • Chris Tavares

    There’s some serious potential perf implications with a lot of anonymous functions around – you should make sure you really, really need actual block scope before going this route.

    • Anonymous

      I couldn’t agree more. Block scope is overrated in most cases.

  • http://twitter.com/PostHopeLive Paul Barton

    This is a good article and point. However covering scope in JavaScript and leaving out hoisting can still leave people confused! This example demonstrates my point http://jsfiddle.net/vF8Cy/

    • http://mutedsolutions.com Derick Bailey

      True – this was only a small piece of scope, though. There’s a lot to cover, more than just hoisting or function scope, to understand how it all works.

      If anyone’s interested, I have a paid screencast that covers a large amount of territory in JavaScript scope – including variable hoisting – at http://www.watchmecode.net/javascript-scope

  • http://twitter.com/ed_xavier Eduardo Xavier

    Too much!! Bellow there is something much  simpler:

    function doSomething(){  
    // outer scope
    var IamHere = doPrivateSomething();  

    function doPrivateSomething(){
    // inner works
    }
    }

  • Brian Wigfield

    FYI Block scope is finally coming in 1.7 with the let keyword