4

More and more javascript has this modular approach where empty functions are returned. You can find it in the source of node.js. It's in the documentation of require.js. What does it do?

define(['jquery'] , function ($) {
    return function() {};
});

If I would return an object, I would just do return {};, although I see no use in returning an empty object. Might wanna put the vars in it. So there is obviously something valuable about this. I'm guessing it has something to do with accessing functions that were in the scope of the returned function.

Here is that construction again, in the AMD Is Not The Answer article:

define(['dep1', 'dep2'], function (dep1, dep2) {
    //Define the module value by returning a value.
    return function () {};
});

But what is the practical benefit above in stead of just returning the semantically meaninful stuff you want to return, e.g. in an object?

And how do you access outside-function-inside-scope things in this way?

function(baz) {
    var foo = true,
        bar = false;

    if (baz) bar = true;

    return function() {}; // wut?
};

Although I am not exactly technically 'challenged', I was hoping someone could explain this in layman's terms, because articles about modularity do not make me happy.

Redsandro
  • 11,060
  • 13
  • 76
  • 106
  • 2
    Maybe the intention is returning an empty *constructor*? The returned function *could* access variables in scope where it was defined; but since it doesn't, I believe that is just a silly example. – bfavaretto Oct 02 '13 at 21:30
  • 1
    I see this as a way to avoid errors, so in this case `jQuery(whatever)` will simply silently fail if jQuery hasn't been otherwise defined. The strategy is questionable and certainly needs some context to explain why it's being used. – RobG Oct 02 '13 at 23:03

1 Answers1

1

You have got your code wrong. It should be self executing function like this:

(function(baz) {
    var foo = true,
        bar = false;

    if (baz) bar = true;

    return function() {}; // wut?
});

So you just forgot ( in front of it. Now you probably will use it as an expression so it will become like this

var singleton = (function(baz) {
    var foo = true,
        bar = false;

    if (baz) bar = true;

    return function() {}; // wut?
});

Now your singleton variable will be a simple empty function.

If you put in

return function() {
  return foo; 
}

it becomes useful as this: singleton() <- returns true

And is very similar to module pattern where you just write:

return {
  myFoo: foo
}

And so you can access it with singleton.myFoo;

This is useful to implement public/private variables so you just return functions/variables you want to expose.

lukas.pukenis
  • 13,057
  • 12
  • 47
  • 81
  • 1
    You probably meant IEFE, then you forgot to call your anonymous function. `(function () { ... })();`. Otherwise `singleton()` will return inner function, not `true`. Also, I failed to understand how `singleton` becomes `{}` at any point in the code. – zaquest Oct 02 '13 at 22:11
  • Also, the whole point of the module pattern is that the returned function has access to the execution context that created it through closures. Returning an empty function keeps the closures but makes no use of them, which is rather pointless. – RobG Oct 02 '13 at 23:00
  • @RobG I have edited. Not an empty object, but an empty function. My bad – lukas.pukenis Oct 03 '13 at 09:13
  • Can you elaborate a bit on why you'd want to `return function() { return foo;}` in stead of a non-self-executioning-function that does `return foo;`? Both return true. – Redsandro Oct 03 '13 at 17:54
  • @Redsandro difference is that if you return function you must call it. Returning function is useful when you want to construct a new function while preserving passed arguments(to IEFE in this case) so you can generate a lot of new functions – lukas.pukenis Oct 03 '13 at 18:05
  • I still don't get it. I've upvoted your answer and will give it some time to see if there will be other responses before I will accept yours. :) – Redsandro Oct 04 '13 at 04:14
  • Accepted for lack of other answers. – Redsandro Nov 18 '14 at 22:18