3

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.

Mark
  • 1,754
  • 3
  • 26
  • 43
  • Aside from the fact that you're not declaring your variables with `var` and for some you will have a leftover function, they all do the same thing in this particular example. Other (more complicated) examples may have different results. – Qantas 94 Heavy Aug 15 '14 at 10:41

3 Answers3

1
// 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.
Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
0

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?.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I'd really like to close this as a duplicate, but it's too many different questions asked in a single post. – Bergi Aug 15 '14 at 11:31
0

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

Sth called IIFE

Hope will help.

Community
  • 1
  • 1
Ace
  • 1,093
  • 2
  • 10
  • 23