Mark
Mark

Reputation: 1852

Javascript Module pattern and closures

I'm trying to get my head around the module pattern in Javascript and have come across various different ways that I can see to do it. What is the difference (if any) between the following:

Person = function() {
    return {
        //...
    }
};
person1 = Person();

function Person2() {
    return {
        //...
    }
}
person2 = Person2();


person3 = function() {
    return {
        //...
    }
}();

person4 = (function() {
    return {
        // ...
    }
})();

person5 = (function() {
    return {
        // ...
    }
}());

They all seem to do the same thing to me.

Upvotes: 3

Views: 92

Answers (3)

Ace
Ace

Reputation: 1383

I've found a extremely detail page explaining this kind of stuff

Sth called IIFE

Hope will help.

Upvotes: 0

Bergi
Bergi

Reputation: 664434

The first two aren't a module pattern, but a factory function - there is a Person "constructor" that can be invoked multiple times. For the semantic difference see var functionName = function() {} vs function functionName() {}.

The other three are IIFEs, which all do exactly the same thing. For the syntax differences, see Explain the encapsulated anonymous function syntax and Location of parenthesis for auto-executing anonymous JavaScript functions?.

Upvotes: 0

Jeremy J Starcher
Jeremy J Starcher

Reputation: 23863

// This creates a function, which then returns an object.
// Person1 isn't available until the assignment block runs.
Person = function() {
    return {
        //...
    }
};
person1 = Person();


// Same thing, different way of phrasing it.
// There are sometimes advantages of the
// two methods, but in this context they are the same.
// Person2 is available at compile time.
function Person2() {
    return {
        //...
    }
}

person2 = Person2();


// This is identical to 'person4'
// In *this* context, the parens aren't needed
// but serve as a tool for whoever reads the code.
// (In other contexts you do need them.)
person3 = function() {
    return {
        //...
    }
}();


// This is a short cut to create a function and then execute it,
// removing the need for a temporary variable.
// This is called the IIFE (Immediate Invoked Function Expression)
person4 = (function() {
    return {
        // ...
    }
})();


// Exactly the same as Person3 and Person4 -- Explained below.
person5 = (function() {
    return {
        // ...
    }
}());

In the contexts above,

  • = function() {}();
  • = (function() {}());
  • = (function() {})();

All do exactly the same thing.

I'll break them down.

function() {}();
<functionExpression>(); // Call a function expression.

(<functionExpression>()); // Wrapping it up in extra parens means nothing.
// Nothing more than saying (((1))) + (((2)))


(<functionExpression>)(); 
// We already know the extra parens means nothing, so remove them and you get
<functionExpression>();  // Which is the same as case1

Now, all of that said == why do you sometimes need parens?

Because this is a *function statement)

function test() {};

In order to make a function expression, you need some kind of operator before it.

(function test() {})
!function test() {}
+function test() {}

all work.

By standardizing on the parens, we are able to:

  • Return a value out of the IIFE
  • Use a consistent way to let the reader of the code know it is an IIFE, not a regular function.

Upvotes: 1

Related Questions