100

I'm studying THREE.js and noticed a pattern where functions are defined like so:

var foo = ( function () {
    var bar = new Bar();

    return function ( ) {
        //actual logic using bar from above.
        //return result;
    };
}());

(Example see raycast method here).

The normal variation of such a method would look like this:

var foo = function () {
    var bar = new Bar();

    //actual logic.
    //return result;
};

Comparing the first version to the normal variation, the first seems to differ in that:

  1. It assigns the result of a self-executing function.
  2. It defines a local variable within this function.
  3. It returns the actual function containing logic that makes use of the local variable.

So the main difference is that in the first variation the bar is only assigned once, at initialization, while the second variation creates this temporary variable every time it is called.

My best guess on why this is used is that it limits the number of instances for bar (there will only be one) and thus saves memory management overhead.

My questions:

  1. Is this assumption correct?
  2. Is there a name for this pattern?
  3. Why is this used?
Patrick Klug
  • 14,056
  • 13
  • 71
  • 118
  • +1, great question. I removed the Three.js tag since this isn't *about* Three.js, but rather a pattern you noticed within it. – Chris Hayes Sep 29 '14 at 03:32
  • 1
    @ChrisHayes fair enough. I tagged it as THREE.js because I thought that THREE.js contributors are the most qualified to answer this but yes, it's a generic JS question. – Patrick Klug Sep 29 '14 at 03:33
  • 2
    I believe it is called closures. You can read about them. – StackFlowed Sep 29 '14 at 03:41
  • 1
    If this is the only place a Bar is instantiated, then it is a [singleton](http://en.wikipedia.org/wiki/Singleton_pattern) pattern. – Paul Sep 29 '14 at 03:57
  • 8
    Not necessarily to save memory, but it can keep state across invocations – Ruan Mendes Sep 29 '14 at 03:59
  • 2
    @wrongAnswer: not exactly. here the anonymous function (which would be the closure) is executed immediatly. – njzk2 Sep 29 '14 at 14:21
  • Really good question, as I'd noticed that and it's actually made JavaScript interesting, as well as ... 'stupid'. Also helped clarify how closures work. – nicodemus13 Sep 29 '14 at 20:05
  • 1
    In the first variation, foo is assigned the result of the inner anonymous function, because the inner anonymous function is being returned as the result of the outer anonymous function and executed immediately. In the second ("normal") variation, foo is assigned the anonymous function itself. So these are not semantically equal variations. They are very different. – Thanasis Ioannidis Sep 30 '14 at 21:26
  • 1
    You've already got good answers, but I'd like to add that there is a great chapter in 'eloquent javscript' that describes the use of modules as a form of namespacing: http://eloquentjavascript.net/10_modules.html - They can get rather complicated though with things like commonjs, requirejs, and curljs and a number of formats like AMD, UMD, etc. I personally hope to use ECMAscript 6's module format and then go with a transpiling approach. – Ape-inago Nov 08 '14 at 09:59

6 Answers6

100

Your assumptions are almost correct. Let's review those first.

  1. It assigns the return of a self-executing function

This is called an Immediately-invoked function expression or IIFE

  1. It defines a local variable within this function

This is the way of having private object fields in JavaScript as it does not provide the private keyword or functionality otherwise.

  1. It returns the actual function containing logic that makes use of the local variable.

Again, the main point is that this local variable is private.

Is there a name for this pattern?

AFAIK you can call this pattern Module Pattern. Quoting:

The Module pattern encapsulates "privacy", state and organization using closures. It provides a way of wrapping a mix of public and private methods and variables, protecting pieces from leaking into the global scope and accidentally colliding with another developer's interface. With this pattern, only a public API is returned, keeping everything else within the closure private.

Comparing those two examples, my best guesses about why the first one is used are:

  1. It is implementing the Singleton design pattern.
  2. One can control the way an object of a specific type can be created using the first example. One close match with this point can be static factory methods as described in Effective Java.
  3. It's efficient if you need the same object state every time.

But if you just need the vanilla object every time, then this pattern will probably not add any value.

MD. Sahib Bin Mahboob
  • 20,246
  • 2
  • 23
  • 45
  • 1
    +1 for correctly identifying the pattern from Addy Osmani's book. You are correct in your naming - this is indeed the module pattern - the revealing module pattern in that by the way. – Benjamin Gruenbaum Sep 29 '14 at 09:17
  • 4
    I agree with your answer, except the 'no out-of-the-box private variables' part. All JS variables are lexically scoped 'out-of-the-box', which is a more powerful/general mechanism than "private" variables (eg. as found in Java); therefore JS supports "private" variables as a special-case of the way it handles all variables. – Warbo Sep 29 '14 at 11:26
  • I think by "private variables", you meant private "object field" – Ian Ringrose Sep 29 '14 at 18:53
  • Thanks, this confirms that I understood what the code does but still leaves the question Why? Why does a project like THREE.js use this pattern extensively on a per-function basis? Why not simply introduce scope on a per-type basis (for the entire sprite file, for example)? What justifies the clearly more verbose version? – Patrick Klug Sep 30 '14 at 00:20
  • 1
    Just for the details: http://www.klauskomenda.com/code/javascript-programming-patterns/#module – Nagaraj Tantri Sep 30 '14 at 03:39
  • @Warbo How exactly is JS more powerful in that sense than Java? I'm pretty sure Java's variables are also lexical scoped. More than that, JavaScript has that function-only scoping issue with closures which other languages don't. (see `do` keyword in Coffeescript and `let` keyword in new proposed JS iterations) – Luka Horvat Sep 30 '14 at 05:27
  • I believe power does depend on the context. Which seems to be a power can be a pain in different context. – MD. Sahib Bin Mahboob Sep 30 '14 at 06:12
  • This problem actually comes from the question, but you reproduced it in the answer: on item 1, the IIFE is not assigned (to `foo`). What is assigned to `foo` is the function returned from the IIFE. The OP seems to understand that, though. – bfavaretto Sep 30 '14 at 21:56
  • 4
    @LukaHorvat : as a matter of fact, javascript is not more "powerful" than other languages (I prefer the term expressive). Actually, it's less expressive, as the only way to protect your variables is enclosing them in function to avoid any variable-reuse nonsense. The Module pattern is a definitive requisite to make good javascript code, but it's not a feature of the language, it's more of a sad workaround to avoid being bitten by the weaknesses of the language. – Falanwe Sep 30 '14 at 23:47
  • I'll accept this answer as it explains the what and the potential why as well as performance impact. I still don't understand why THREE.js isn't using a per-type IIFE instead (much less verbose, same benefits) but it's probably a personal choice of the dev. – Patrick Klug Oct 01 '14 at 04:48
  • "This is the way of having private object fields in JavaScript as it does not provide the private keyword or functionality otherwise.". Don't ES6 modules keep everything private now? what's the difference in that vs a closure? – PositiveGuy Jul 12 '18 at 19:18
11

It limits the object initialization costs and additionally ensures that all function invocations use the same object. This allows, for example, state to be stored in the object for future invocations to use.

While it's possible that it does limit memory usage, usually the GC will collect unused objects anyways, so this pattern is not likely to help much.

This pattern is a specific form of closure.

Fengyang Wang
  • 11,901
  • 2
  • 38
  • 67
  • 1
    In JS it's usually reffers as 'module' – Lesha Ogonkov Sep 29 '14 at 03:40
  • It (using a closure-based solution) probably increases the memory consumption actually – zerkms Sep 29 '14 at 03:41
  • 2
    I wouldn't call it "a specific form of closure", per se. It's a pattern which *uses* a closure. The pattern's name is still up for grabs. – Chris Hayes Sep 29 '14 at 03:42
  • It's like having static variables in C. – Ruan Mendes Sep 29 '14 at 03:57
  • 4
    Does it really need a name? Does everything have to be a pattern? Do we really need an endless taxonomy of "module pattern" variants? Can't it just be "an IIFE with some local variables that returns a function?" – Dagg Nabbit Sep 29 '14 at 04:06
  • 3
    @DaggNabbit When the question is "what is this pattern called"? Yes, it needs a name or else a convincing argument that it doesn't have one. Besides, patterns exist for a reason. I don't understand why you're railing against them here. – Chris Hayes Sep 29 '14 at 04:21
  • 4
    @ChrisHayes if it needs a name, why would you need to make an argument that it doesn't have one? That doesn't make any sense. If it needs one, it must not have one. I have no problem with patterns, but I don't think it's necessary to classify every single simple idiom as a pattern. Doing that leads to thinking in limited ways ("Is this a module pattern? Am I using the module pattern correctly?" vs. "I have an IIFE with some local variables that returns a function, does this design work for me?") – Dagg Nabbit Sep 29 '14 at 04:56
  • I guess it would potentially reduce the number of objects the GC needs to collect dramatically. What I don't understand is why THREE.js uses this pattern per-function, rather than introducing a scope around an entire class. (why not put the Sprite itself in a IIFE). seems convoluted to do it per-function. – Patrick Klug Sep 29 '14 at 06:55
  • @PatrickKlug this pattern is kind of an anti pattern in even more modern JS, it makes debugging hard because of the closure - closures are awesome for binding state to functions - but they're rather pointless for privates. – Benjamin Gruenbaum Sep 29 '14 at 09:19
8

I'm not sure if this pattern has a more correct name, but this looks like a module to me, and the reason it is used is to both encapsulate and to maintain state.

The closure (identified by a function within a function) ensures that the inner function has access to the variables within the outer function.

In the example you gave, the inner function is returned (and assigned to foo) by executing the outer function which means tmpObject continues to live within the closure and multiple calls to the inner function foo() will operate on the same instance of tmpObject.

itsmejodie
  • 4,148
  • 1
  • 18
  • 20
5

The key difference between your code and the Three.js code is that in the Three.js code the variable tmpObject is only initialised once, and then shared by every invocation of the returned function.

This would be useful for keeping some state between calls, similar to how static variables are used in C-like languages.

tmpObject is a private variable only visible to the inner function.

It changes the memory usage, but its not designed to save memory.

mcfedr
  • 7,845
  • 3
  • 31
  • 27
5

I'd like to contribute to this interesting thread by extending to the concept of the revealing module pattern, which ensures that all methods and variables are kept private until they are explicitly exposed.

enter image description here

In the latter case, the addition method would be called as Calculator.add();

carlodurso
  • 2,886
  • 4
  • 24
  • 37
0

In the example provided, the first snippet will use the same instance of tmpObject for every call to the function foo(), where as in the second snippet, tmpObject will be a new instance every time.

One reason the first snippet may have been used, is that the variable tmpObject can be shared between calls to foo(), without its value being leaked into the scope that foo() is declared in.

The non immediately executed function version of the first snippet would actually look like this:

var tmpObject = new Bar();

function foo(){
    // Use tmpObject.
}

Note however that this version has tmpObject in the same scope as foo(), so it could be manipulated later.

A better way to achieve the same functionality would be to use a separate module:

Module 'foo.js':

var tmpObject = new Bar();

module.exports = function foo(){
    // Use tmpObject.
};

Module 2:

var foo = require('./foo');

A comparison between the performance of an IEF and a named foo creator function: http://jsperf.com/ief-vs-named-function

Kory Nunn
  • 273
  • 3
  • 5
  • 3
    Your 'better' example only works in NodeJS and you haven't explained how it's better. – Benjamin Gruenbaum Sep 29 '14 at 09:18
  • Making a separate module isn't "better", it's just different. In particular, it's a way to collapse higher-order functions down to first-order objects. First-order code tends to be easier to step through, but is generally more verbose and forces us to reify intermediate results. – Warbo Sep 29 '14 at 11:30
  • @BenjaminGruenbaum Modules aren't only in Node, there are many client-side module solutions, for example, browserify. I consider the module solution to be "better" because it is more readable, easier to debug, and is more explicit about what's in scope, and where. – Kory Nunn Oct 01 '14 at 00:33