4

With a js module pattern, I think functions are commonly defined like this:

var loadData = function(myParam1, myParam2){}

However, the js module pattern still works with functions defined like this:

function loadData (myParam1, myParam2){}

Is there any practical reason to define functions as variables in a js module? Is a function variable generally expected from a design standards perspective for a publicly exposed method within a js module? Or is the implementation style really more of a matter of personal preference?

6
  • 1
    I don't know if I would call what you are demonstrating above a "module pattern" -- it's just function declaration. Perhaps someone can correct me, but I think the only difference between the first one (an anonymous function assigned to a variable) and the second one (a named function) is that the second one will have an associated "name" property. Commented Mar 20, 2017 at 18:21
  • 2
    The second format is evaluated first so even if you define it last in the file it will be accessible earlier in your file. The first example acts as a regular variable declaration and is not accessible before declaration. Commented Mar 20, 2017 at 18:22
  • As a follow-up to what @anied said, one can name the first example too like var loadData = function loadMyData(myParam1, myParam2){} Commented Mar 20, 2017 at 18:29
  • I understand that the first example I provided above is a function expression. What I don't understand is if I should always use function expressions for functions that will be exposed via module pattern, if there are particular scenarios where I should use them or if it's really just a personal preference? Commented Mar 20, 2017 at 18:50
  • @anied The real difference is that for the function declaration, the value initialisation is hoisted with it. (The .name property no longer makes a difference since ES6, even the assignment form creates one) Commented Mar 20, 2017 at 19:00

2 Answers 2

2

Module pattern is usually augmented by IIFE pattern:

(function(){
})();

Here is an example:

var MODULE = (function(){
    function anotherLoadData(myParam1, myParam2){
        console.log('another load data')
    }
    return {
        loadData : function(myParam1, myParam2){ 
            console.log('load data');
        },
        anotherLoadData : anotherLoadData
  }
})();

MODULE.loadData();
MODULE.anotherLoadData();

So you see, the way you declared your functions doesn't relate to js module pattern.

Sign up to request clarification or add additional context in comments.

7 Comments

i'm only referring to functions defined within the js module pattern not the overall js module implementation
the OP says "js module pattern". This term is special. More reference here on another SO post. I guess you might want to change the question title if you mean to ask something other than the "js module pattern"
hi sing i'm referring to the functions defined above as they would be defined in js module pattern
js module pattern relates to namespacing of certain properties and behaviors. It doesn't matter how the function is declared. I have explained that in the answer. UNLESS, you understand IIFE and are talking about the difference in between var MODULE = (function(){})(); and (function(module){})(MODULE);
ok so you're saying that using a function or function expression within a js module is purely a matter of personal preference without any implications?
|
-1

Will this edited answer will be better: [Learning JavaScript Design Patterns][1]

The Module Pattern

The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.

In JavaScript, the Module pattern is used to further emulate the concept of classes in such a way that we're able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope. What this results in is a reduction in the likelihood of our function names conflicting with other functions defined in additional scripts on the page.

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.

This gives us a clean solution for shielding logic doing the heavy lifting whilst only exposing an interface we wish other parts of our application to use. The pattern is quite similar to an immediately-invoked functional expression (IIFE - see the section on namespacing patterns for more on this) except that an object is returned rather than a function.

It should be noted that there isn't really an explicitly true sense of "privacy" inside JavaScript because unlike some traditional languages, it doesn't have access modifiers. Variables can't technically be declared as being public nor private and so we use function scope to simulate this concept. Within the Module pattern, variables or methods declared are only available inside the module itself thanks to closure. Variables or methods defined within the returning object however are available to everyone.

History

From a historical perspective, the Module pattern was originally developed by a number of people including Richard Cornford in 2003. It was later popularized by Douglas Crockford in his lectures. Another piece of trivia is that if you've ever played with Yahoo's YUI library, some of its features may appear quite familiar and the reason for this is that the Module pattern was a strong influence for YUI when creating their components.

Examples

Let's begin looking at an implementation of the Module pattern by creating a module which is self-contained.

var testModule = (function () {

  var counter = 0;

  return {

    incrementCounter: function () {
      return counter++;
    },

    resetCounter: function () {
      console.log( "counter value prior to reset: " + counter );
      counter = 0;
    }
  };

})();

// Usage:

// Increment our counter

testModule.incrementCounter();

10 Comments

Why is this an answer and not a comment?
Depends how you see it. I'm not giving the fish, but teaching how to catch it!
Someone on SO once told me to keep links only for reference. The links might be broken(later years)
Agree with singsuyash-- links are fine for supplementary material, but they are not an answer in and of themselves.
@jmmontero -- please see the following link on StackExchange Meta: meta.stackexchange.com/questions/8231/…
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.