views:

223

answers:

4

I've started using the Sencha Touch / ExtJS JavaScript framework and have am noticing a wide use of nested, anonymous functions. For example, this is a common way to start your app:

Ext.setup({
    blah: blah,
    onReady: function() { 
        my
        fairly
        long
        startup
        code }
});

It's been a while since I've done JavaScript programming; to me, defining a nested anonymous function like this--inside of a function call--is not as easy to read as the following:

Ext.namespace('myvars');

myvars.onReadyFcn = function() { 
     my
     fairly
     long
     startup
     code
};

Ext.setup({
    blah: blah,
    onReady: myvars.onReadyFcn
});

I understand there are some real benefits to using anonymous functions in certain situations (e.g., maybe it's one-time code, maybe you don't want to add another function to the global namespace, etc.). That said, is there anything technically wrong/detrimental to using this latter (perhaps more verbose) method if you find it easier to read?

Thanks!

+2  A: 

I used to have the same feelings you did when I first started encountering nested anonymous functions.

Now that I've gotten much more used to them I actually find nested anonymous functions much easier to read as long as they're only used in one spot. When code is written that way, all the code I'm interested in is in a single spot and I don't have to jump around the file nearly as much to figure out what the code is trying to do.

Keep in mind, though, that my opinion only applies if the code is only used in one location. If you keep repeating the same anonymous function in multiple places...I still prefer to break it out like your second example.

Justin Niessner
+1  A: 

In a way, you may have answered your own question. The OnReady function is only run once. for maintainability, it might be a good idea to separate out your code so that you have a section for layout, a section for events, and a section for business logic in your code.

One thing to consider perhaps is that Sencha Touch is geared towards mobile devices that may sometimes have limited resources for you to work with. With that in mind, it might be necessary to structure your code to make it as small and efficient as possible. Your proposed code snippet may be ignoring those constraints that mobile platforms have to deal with.

It Grunt
+3  A: 

I don't think there is anything wrong using separate functions, depending on the purpose. For a setup function or onReady functions I will like anonymous functions, for callback functions that are really small piece of code like 1 or 2 simple line I will use anonymous functions. For callbacks I often like to use a separate function however, I find it easier to read and especially with most frameworks giving an easy way to pass parameters to the callbacks when making XHR.

However, one advantage nested anonymous functions gives you is the closures around variables that sometimes you might end up needing to pass as parameters if you separate the function.

It is a very tough question to answer because it will be a question of style, performance, purpose that will be different depending what is the purpose of the code you're writing.

SBUJOLD
In case anyone else isn't sure what "closures" means (I wasn't), there's a great explanation here: http://www.javascriptkit.com/javatutors/closures.shtml
Clint Harris
+2  A: 

I use both ways all the time without thinking too much about what is better. And I believe that in terms of performance if you are worried about a mobile device download time or parsing time then you will end up using some JS Minifier (or maybe the Closure Compiler).

Anyway, I do have a criteria that seems helpful to me to decide whether the function should be anonymous or not:

If I had a really good name for the function then it shouldn't be anonymous

What I mean is if your function will be named onSetupReady then the function is not explaining what it does, instead, its name is defining where it should be used (and that would usually be one only place which will call that function). So if that is the case then you can choose to make the function anonymous or not. I usually choose anonymous.

But, if your functions does one just one thing, and that thing in not really obvious, and you are tempted to put a single line comment in the first line of the function (or whatever) to explain what it does. then I won't do that, and I would choose a good name for this function. And I enforce this rule if the event which trigger this function is not so obvious for that function. Examples:

Anonymous OK

Ext.Window({
    listernes: { 
        beforeclose: function() { // this function has only one purpuse
            Ext.Msg.show({        // and can be named, but to me is ok, as it
                title:'Close?',   // is really easy to see what it does.
                msg: 'You are sure?',
                fn: function(btn) {
                    if (btn === 'cancel') {
                        return false;
                    }
                },
                animEl: 'elId',
                icon: Ext.MessageBox.QUESTION
            });
        }
    }
}).show();

Anonymous NOT Recommended

var insertExtraToolbar = function() {
    var containerNbar = theGrid.getBottomToolbar().getEl().parent().dom;
    theGrid.elements += ',nbar';
    theGrid.createElement('nbar', containerNbar);
};
theGrid.on('render', insertExtraToolbar);
Protron