2

I have some third-party Javascript that has statements like this:

FOO = function() {
   ...functions() ... 
   return { hash }
}();

It is working as designed but I'm confused by it. Can anybody define what this structure is doing? Is it just a weird way to create a class?

Clutch
  • 7,404
  • 11
  • 45
  • 56

5 Answers5

5

This is a technique that uses closure. The idiom is well-known, but confusing when you first see it. FOO is defined as the object that the outermost function() returns. Notice the parenthesis at the end, which causes the function to evaluate and return { hash }.

The code is equivalent to

function bar() {
   ...functions() ... 
   return { hash }
};

FOO = bar();

So FOO is equal to { hash }. The advantage of this is that hash, whatever it is, has access to stuff defined inside the function(). Nobody else has access, so that stuff is essentially private.

Google 'Javascript closure' to learn more.

brainjam
  • 18,863
  • 8
  • 57
  • 82
  • Another important point of the pattern that your example misses out is that the self invoking anonymous function avoids polluting the global namespace i.e. taking your example, there would be no bar `function` in global scope that can be directly invoked. – Russ Cam Apr 01 '10 at 19:38
  • Absolutely. I just wanted to 'parse' it conceptually. But yes, once you understood that part, you'd want to put it back together again without defining `bar`. – brainjam Apr 01 '10 at 20:21
1

Js doesn't really have classes, per se, but "prototypes". This means that no two objects are ever of the same "type" in the normal type-safe sense, and you can dynamically add members to one instance while leaving the other unmolested. (which is what they have done).

Believe it or not, the syntax they have used is probably the most lucid, as it doesn't try to hide behind some C-style class syntax.

Doug Crockford's Javascript: The Good Parts is a quick read, and the best introduction to OOP in js that I've come across.

BnWasteland
  • 2,109
  • 1
  • 18
  • 14
0

You're missing an open parens, but it is basically a way of usually hiding information within an object i.e. a way of setting up private and privelaged methods.

For example

var foo = (function() {
   /* function declarations */
   return { /* expose only those functions you 
               want to expose in a returned object 
            */ 
          }
})();

Take a look at Papa Crockford's Private Members in JavaScript. This is basically the pattern you are seeing, but in a slightly different guise. The function declarations are wrapped in a self-invoking anonymous function - an anonymous function that is executed as soon as it's declared. Since the functions inside of it are scoped to the anonymous function, they will be unreachable after the anonymous function has executed unless they are exposed through a closure created by referencing them in the object returned from the execution of the anonymous function.

It's generally referred to as the Module Pattern.

Russ Cam
  • 124,184
  • 33
  • 204
  • 266
  • Don't you need a closing parenthesis to balance that opening paren? Also, what would the consequences be of omitting that pair? Wouldn't the function still be anonymous? – brainjam Apr 01 '10 at 20:20
  • Looks like the extra parens are only stylistic. See http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth#comment-41261478 – brainjam Apr 01 '10 at 20:41
  • @brainjam - thanks, missed the closing parens. In this instance, they are optional, but not if you want to execute the function in global scope and not assign it to a variable. For consistency and to avoid a "do I need them in this case/do I not need them in this case?" dilemma, I'd recommend always using them when immediately invoking an anonymous function. – Russ Cam Apr 01 '10 at 21:22
0

That's not actually a class, just an object. I'd recommend reading this: http://javascript.crockford.com/survey.html

Because JavaScript doesn't have block scope, your choice is (mostly) to have all variable reside in global or function scope. The author of your snippet wants to declare some local variables that he doesn't want to be in the global scope, so he declares an anonymous function and executes it immediately, returning the object he was trying to create. That way all the vars will be in the function's scope.

noah
  • 21,289
  • 17
  • 64
  • 88
0

The parans at the end make this the Module Pattern, which is basically a way to have a single instance of an object(Singleton) while also using private variables and functions.

Since there's closures hash, if it's itself an object or function, will have access to all variables declared within that anonymous Singleton object.

Bob
  • 7,851
  • 5
  • 36
  • 48