Stop writing anonymous functions

Today I want to talk to you about anonymous functions in Javascript and how we can write our code in such a way to get the most out of our development tools. But first:

p_anonymous-function

What are anonymous functions?
In javascript you can create a function in two ways, through a function declaration or through a function expression.

Using a function declaration looks like this:

function hello() {                  // <-- creates a function named 'hello'
  alert('Hello World!');
}

Using a function expression looks like this:

var hello = function() {            // <-- creates an anonymous function assigned
  alert('Hello World!');            //     to a variable named 'hello'
};

You can even combine the two approaches:

var hello = function hello() {      // <-- creates a function named 'hello'
  alert('Hello World!');            //     assigned to a variable named 'hello'
};

So there is a variety of ways to create a new function. Which is best?

Disadvantages of anonymous functions
In browsers that support the name attribute on function objects there will be no name available for the second helloWorld function. Why not? Because it might as well have been created like this:

var x = y = z = function() {...};

So in a function expression like this, which would be the one and only real name of the function? Or what to do with auto-invoking function expressions such as this:

(function() {
})();

Apart from the name variable, we also won’t get a name for these functions in stack traces or as the source of log messages. These are valuable debugging tools. We should write our code in such a way as to be able to get maximum benefit of these tools.

Changing our ways
Anonymous functions are often used as part of literal object expressions, like this:

var Speaker = {
  speak: function() {
    alert('Hello World!');
  }
};

What I am proposing is that we built in some redundancy in these types of code, to aid our development tools, and write such code like this:

var Speaker = {
  speak: function Speaker_speak() {
    alert('Hello World!');
  }
};

One day you’ll have to debug some very weird issue happening only in production of which you only have some logging and then you’ll thank yourself for putting in the extra typing to make sure your functions are not all anonymous!

What do you think?
Let me know your take on this in the comments.

9 responses to “Stop writing anonymous functions

  1. Hi,

    I’m new to this. What is the advantage of an anonymous function apart from it being quicker because you don’t have to think up a suitable name.

    In class they told us to think up good variable (and function) names so that the code almost self-comments! I use this approach and I think it helps me but I haven’t tried any other way so can’t say which is better.

    My 50 cents/pence worth!

  2. Hi deemyboy. Indeed there doesn’t seem to be much of an advantage for anonymous functions… Which is kind of the reason I wrote this post.

    Function expressions (which can be anonymous but don’t have to be) have as advantage that you can pass their result (the created function) to another function as an argument. This is frequently done:

    $('#some-div').on('click', function() {
    alert('div with ID some-div was clicked.');
    });

    on is a jQuery function in the above example. It’s called with two parameters: the name of the event (‘click’ in this case) and the anonymous listener function. This is a very common example of using anonymous functions. However you could just as well use a named function here:

    $('#some-div').on('click', function someDivClicked() {
    alert('div with ID some-div was clicked.');
    });

    So that’s what this post is about. I’m making an argument against the use of anonymous functions because mostly you don’t need them. You can use named functions just as well and enjoy the benefits of that during debugging / logging / introspection etc.

  3. Ok: in most cases named functions are more clear at just the cost of writing some more characters; and the saying “write less, do more” is often misunderstood.
    But the anonymous function in your post could perhaps be interesting as an easy way to encapsulate a bit of code:

    (function() {
    // code that can be run just once
    })();

    Well, you can just remove the function() stuff and the code will still be run just once. But if we add

    (function() {
    var i, j;
    // code that uses i and j and can be run just once
    })();

    The scope of i and j is the anonymous function’s body; they won’t pollute the global scope. Note that in other languages the braces alone will work the same way (i and j scope is limited to inside the braces):
    {
    var i, j;
    // code that uses i and j and can be run just once
    }
    but not in javascript.

    So
    (function() { var i, j; … })();
    could be “not so bad a synonym” of C/C++ or Java’s
    { int i, j; … }

    That said, I’ve never done this… Just thinking for the sake of it :P

  4. Not so bad, indeed… just coding patterns.
    When declaring variables, myVar1, myVar2 will work, but choosing a self explanatory name is usually “better”.
    When declaring variables global scope will work, but restricting their scope to just the code portion in which they are intended to be used, is usually “better”

  5. Actually Giovanny, your proposal is already a well established pattern. It’s called auto-invocation. It’s actually used a lot. So yeah it’s a very good idea.

    Still, there is nothing stopping you from naming an auto-invoking function so why not do it? :)

  6. Because without a name it cannot be executed (except that unique auto invocation).
    If it’s what the enclosed code is intended for, e.g. initialization code to be run only once as soon as we have finished defining it, the best name for the function might be no name at all :)
    The only “good” exception to your proposal I can think of now

  7. True. But actually I think it’s better to use a dependency management system like AMD. In that kind of code your initialization function is called by the dependency management system and you get all the same benefits as with an auto-invoked init function, plus a lot more.

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