3

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?

details1
  • 185
  • 1
  • 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. – Alexander Nied Mar 20 '17 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. – E. Sundin Mar 20 '17 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){}` – E. Sundin Mar 20 '17 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? – details1 Mar 20 '17 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) – Bergi Mar 20 '17 at 19:00
  • @Bergi -- yes, agreed -- E. Sundin also called that out shortly after I posted and I linked a duplicate post supporting that statement. Interesting note about the `name` property, though. – Alexander Nied Mar 20 '17 at 19:01

2 Answers2

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.

singsuyash
  • 1,337
  • 2
  • 13
  • 27
  • i'm only referring to functions defined within the js module pattern not the overall js module implementation – details1 Mar 20 '17 at 18:47
  • the OP says "js module pattern". This term is special. More reference here on another [SO](http://stackoverflow.com/questions/17776940/javascript-module-pattern-with-example#19801321) post. I guess you might want to change the question title if you mean to ask something other than the "js module pattern" – singsuyash Mar 20 '17 at 18:52
  • hi sing i'm referring to the functions defined above as they would be defined in js module pattern – details1 Mar 20 '17 at 18:54
  • 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);` – singsuyash Mar 20 '17 at 18:57
  • 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? – details1 Mar 20 '17 at 19:00
  • I think the SO Post to which this Post is duplicated to, answers your question. Just for your help, i think you are getting confused by "what is the difference of scope for both the ways of function declaration".. no offense, just curious! – singsuyash Mar 20 '17 at 19:03
  • I updated the title to be more specific/descriptive. sounds like the function implmentation style makes no difference. another poster mentioned something about a difference in a 'name' attribute but it sounds like maybe this doesn't matter in ES6 and is only a minor unimportant difference between the implementations – details1 Mar 20 '17 at 19:29
-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();
funcoding
  • 663
  • 5
  • 9
  • Why is this an answer and not a comment? – Alexander Nied Mar 20 '17 at 18:39
  • Depends how you see it. I'm not giving the fish, but teaching how to catch it! – funcoding Mar 20 '17 at 18:42
  • Someone on SO once told me to keep links only for reference. The links might be broken(later years) – singsuyash Mar 20 '17 at 18:45
  • Agree with singsuyash-- links are fine for supplementary material, but they are not an answer in and of themselves. – Alexander Nied Mar 20 '17 at 18:47
  • I'm not agree with the downvote! The link provides full answer to the question. If you are downvoting based on the link not available, you should consider also when the other users are using fiddle links to provide answer for a question. – funcoding Mar 20 '17 at 18:53
  • I ask the moderator of the website to review this link. It has been available more than 4 years and if an user is looking for an answer to the question it is expected for that user to look for resources and try some code. That's how you learn rather than providing an answer to the question. – funcoding Mar 20 '17 at 18:55
  • 2
    @jmmontero -- please see the following link on StackExchange Meta: https://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers – Alexander Nied Mar 20 '17 at 18:56
  • @jmmontero Exactly that's the problem - the linked website provides the answer, your post ("answer") does not – Bergi Mar 20 '17 at 19:02
  • [When someone goes on Stack Overflow, the question "answer" should actually contain an answer. Not just a bunch of directions towards the answer.](https://meta.stackexchange.com/a/8259/194698) – Krease Mar 20 '17 at 19:09
  • Ok. I got the point! I will improve it next time! – funcoding Mar 20 '17 at 19:20