Proposed coding convention for closures

| 6 Comments

By now, many of us have gotten used to using closures in JavaScript to define a scope that holds private variables and utility functions so that we don't have to put these in the global namespace. The idiomatic code looks like this:

(function() {
      var private_var;    // Visible only inside this function
      function helper_function() { ... }
      
      // export an object or function to the global namespace
})();  // Invoke the outer function

The outer function exists only to create a scope to hold our internal variables. It has no name and is invoked exactly once, immediately after being defined. The fact that this is a function expression (rather than a statement-like function declaration) means that we can invoke it immediately after defining it. The parentheses before the function keyword and after the closing } are required because otherwise the JavaScript interpreter would think that this was a function declaration and would complain about the missing function name.

That unusual opening parenthesis before "function" serves another important purpose in this idiom. It alerts us to the fact that this function is being used idiomatically, that it exists solely to create a scope and that it is going to be invoked immediately.

So far, so good. But I've finally gotten around to reading Douglas Crockford's JavaScript: The Good Parts and it has made me think that an additional explicit naming convention would be helpful. (As an aside, Crockford's short book is worth a read, though I find that I disagree with some of his coding conventions. I'm tempted to write a review titled "JavaScript: The Good Parts: The Good Parts"...)

When the function keyword is the first token in a new JavaScript statement, the interpreter expects to see a function declaration, not a function expression. That's why we needed the idiomatic parentheses in the code above. But when the function keyword is used as part of an assignment or as an argument to some other function, those parentheses are not required. Crockford's book includes code like this (page 37):

var myObject = function() {
    var value = 0;

    return { // 7 lines of code omitted here
    };
}();

When I first read the assignment statement it appears to me (despite the name of the variable) that it is a function value being assigned. In fact, however, the function is merely there to establish a scope for private variables. The function is invoked as soon as it is defined, and it is the return value of the function that is assigned. The problem is that I don't realize this until I read all the way down to the end of the function. Appendix E takes this to an extreme. The code begins:

var json_parse = function() {

It looks like we're creating a function and assigning it to the variable json_parse. But five pages later we see:

}();

Now we realize that the value assigned to json_parse is not the function we thought it was, but the function returned by that function.

Another example appears on page 40:

String.method('deentityify', function() {
   // 25 lines omitted
}());

It appears at first that we're passing a function as the second argument of the invocation of String.method. It is not 'till we read all the way through this function that we realize that we're passing the result of invoking the function.

So, how can this code be improved? One way would be to use the idiomatic parentheses around function expressions that are going to be immediately invoked even when they are not necessary. That would turn the code above into this:

String.method('deentityify', (function() {
   // 25 lines omitted
})());

I think that would be helpful, but I think we can do better. Function expressions are allowed to have names, and those names are only visible within the body of the function (allowing such a function to invoke itself recursively, for example). So let's say that when we're going to define a function for the purpose of creating a scope we make that explicit by giving it a dummy name like "scope" or "closure" or "invocation". This results in code like:

var myObject = function scope() {
   // code omitted
}();

String.method('deentityify', function invocation() {
   // 25 lines omitted
}());

Your thoughts are welcome in the comments. Has anyone else proposed a convention like this? What's the best name to use for these functions?

Update: I suppose we could also simply adopt a comment-based convention:

var myObject = /* return value of */ function () {
   // code omitted
}();

String.method('deentityify', /* result of */ function() {
   // 25 lines omitted
}());

Update 2: It turns out that Douglas Crockford is about 2 months ahead of me. In March he updated jslint to (optionally) issue warnings about immediate invocation of function expressions unless the entire invocation appears in parentheses, and also to warn if a function is parenthesized and is not immediately invoked. So Crockford's convention looks like the following:

var myObject = (function () {
   // code omitted
}());

String.method('deentityify', (function() {
   // 25 lines omitted
}()));

Note that Crockford wraps the invocation in parens, not just the function. That is, he uses ()) at the end instead of (the more commonly used) )(). He has said that he'll update his book to follow these conventions in the next printing.

6 Comments

I believe it is a best-practice to have a name even for situation where anonymous function is just OK. With name, when some exception is thrown, it is easier to locate root in stack trace.

I like the idea of giving the function an identifier.

In terms of a comment based convention, this is what I use in practice, but following the ActionScript/ ECMAScript 4 / Pascal convention in terms of placement (including a colon) - based on something Nicholas Zakas proposed a few years ago:-

var Person /*: Function*/ = (function(){

})();

Or your example:-

String.method('deentityify', (function() /*: Function*/ {
// 25 lines omitted
}()));

I'm following the same convention myself, even before reading The Good Parts, so I had the same issue with this coding convention used in the book. The purpose of my convention is exactly the one you're describing.

Recently, though, I discovered there's yet another idiom for solving this problem of scope. Most of the time when we use these self-executing lambdas we return objects from them. So we could just as well do:


var obj = new function () {
// This would be yet another convention so
// that we don't have to wonder what "this"
// points to.
var self = this;
};


The above idiom does not have issues with "this" binding as "this" is used only for that instantiation. The advantage of this idiom would be the warning that the new operator should trigger in our minds. I'm not aware of any disadvantages.

David, by the way, as far as I know, function expression names are globally visible in IE6. Old browser, I know, but there are plenty of developers that have to support it. And maybe there are problems with more recent versions of IE too.

Ionut,

using new here, while does the job, has a side effect, which is the .constructor property.

It may be thought of as a feature, though many people think it's a "weird construction" (as does Douglas Crockford and his JSLint).

Proponents of this construction sometimes say it's a good way to build a constructor function that only has one instance, but it's actually not true.

Having this:

var obj = new function() {
this.a = 5;
};

you can do this:

var obj2 = new obj.constructor();
alert(obj2.a); // 5

Basically, every useful thing that comes from "new function" can be accomplished with a normal closure.

Marek, you're right about the constructor property. But even with a new instance, what you can get with it is the public API. The private variables are there too, but still private. Anyway, I'm not looking for a Singleton (anti-)pattern. I was rather depending on that "weird construction" to signal people "Hey, this is doing something special".

And as usual, I may be wrong in some aspects, so please feel free to make the appropriate corrections.

Hi David and all of this people who's comment this topic. First of all, sorry for my english. I think, code is for programmer. Yes. Good convention is much better for reading. But if reading is not understand the code, everything is loosing. JavaScript is a language hard for reading. Everyone have self styling, self convention etc. Someone uses prototype inheritance, another classical and this is confused for reading.

Julian Turner in code something like this:

var Person /*: Function*/

I except the value of variable Person is Function pointer. Not returning value of the Function from right side. This is confused for me.
Method on David code:

var myObject = /* return value of */ function

Is so much readable.

One my dummy way. With capsulate Function.apply in global scope. I think, this is not right way, but this is another view of the problem.

function execute(func, _this, args)
{
return func.apply(_this, args);
}

var myObject = execute(function(){return 10;});

Whit respect!

Leave a comment

Books

Comprehensive coverage of Ruby 1.8 and 1.9

"The New Most Important Ruby Book"
Peter Cooper,
rubyinside.com

Completely updated for Ajax and Web 2.0

"A must-have reference"
Brendan Eich,
creator of JavaScript

The classic Java quick-reference

Advertising

Pages

Hosted By

Powered by Movable Type 4.21-en