1

I'm working on implementing the Javascript module pattern, and I understand how to use it pretty well. What I don't understand is the concept of what happens to the private variables and methods once the function has run and the return value been assigned.

If I have a module like so:

var myModule = (function() {

var privateVar1, privateVar2 = 10, privateLogger, privateHello;

privateLogger = function(someInput) {
    console.log(someInput);
};
privateHello = function() { console.log('Hello World!');}

  return {
    publicVar: 'myName',
    publicCounter: 0,
    publicIncrementor: function(bar) {
        bar++;
        privateLogger(bar);
        privateHello();
    }
  }
})();
console.log(myModule);
console.log(myModule.publicIncrementor.toString());

When I run the file, I then get an output of:

{ publicVar: 'myName',
  publicCounter: 0,
  publicIncrementor: [Function] }
function (bar) {
  bar++;
  privateLogger(bar);
  privateHello();
}

From this, it seems like myModule is now a variable that only knows what publicVar, publicCounter and publicIncrementor are. So how does it know what privateHello is? Where does that function definition exist after instantiation? It's not a part of myModule (the console.log(myModule) doesn't show it). It's not a global function (avoiding that is the point of this pattern). So where does that function definition live now?

Or is it that the privateHello function gets re-defined every time I call myModule.publicIncrementor?

R V
  • 133
  • 1
  • 8

2 Answers2

2

This is where closures pop in. The privateHello, privateLogger, privateVar1 and privateVar2 are scoped to your immediately invoked function, and when your publicIncrementor function is accessing these private variables (which are outside the publicIncrementor scope), a closure is created.

So, to answer your question: it lives on the closure now. About your question if it's redefined each time, I'm not 100% sure, but as far as I know, a closure is recreated each time you access a variable from outside the local scope, but it doesn't redefine the objects, in stead of that it will always refer to the same objects.

There are a lot of interesting answers that cover closures, so you might want to take a look at the following answer: How do JavaScript closures work?

Community
  • 1
  • 1
g00glen00b
  • 41,995
  • 13
  • 95
  • 133
  • Thanks, in some way what I just needed was the term to describe what's happening. So just letting me know to research closures is a pretty big help. – R V Nov 07 '14 at 17:58
  • Also in looking at it, I was ignoring the IIFE part of this exercise, which is a big oversight as it as a scope question. – R V Nov 07 '14 at 18:09
  • This link was very helpful: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures – R V Nov 07 '14 at 18:14
1

In your original code (before the question was updated) the privateHello was missing in the variable declaration list so your privateHello was actually becoming global.

Now you've added privateHello to the var list (well spotted), so it is currently just a local variable in the scope of your module constructor function.

I'll try to answer your questions now.

From this, it seems like myModule is now a variable that only knows what publicVar, publicCounter and publicIncrementor are. So how does it know what privateHello is?

myModule instance does not "know" privateHello directly in a sense that you could somehow "reach out" to privateHello only having myModule.

But the constructor function used to create myModule declares privateHello in a local variable in its body.

Where does that function definition exist after instantiation?

Somewhere in the memory.

It's not a part of myModule (the console.log(myModule) doesn't show it).

It is. It is just not assigned to any property of myModule.

It's not a global function (avoiding that is the point of this pattern).

Now it is not, in a previous version of your question it was.

So where does that function definition live now?

Physically it is somewhere in the computer memory. Logically it is just a local variable in the module constructor function. Where does privateVar1 live? They're probably neighbours with privateHello.

Or is it that the privateHello function gets re-defined every time I call myModule.publicIncrementor?

Hard to answer without knowing the semantics of "re-defined". It will be probably the same "instance" of the function every time, but I guess this is an implementation detail. Are you worried about getting new exemplars of the locally defined function? Don't.

lexicore
  • 42,748
  • 17
  • 132
  • 221
  • Yep, I did edit the question to change that. When I was running some checks in Node I was logging the global object and seeing the privateHello function, but not the privateIncrementor, and was confused. However then I realized that it was because of the missing var. I edited it because I knew the reason for what I was seeing and it wasn't really the question I was asking. – R V Nov 07 '14 at 17:49
  • Can you tell me how I could log and inspect the text of myModule's constructor function? If I was able to do so, would I see privateHello in the output of that? – R V Nov 07 '14 at 17:55
  • @RV Having just `myModule` instance? I think you can't. If I got your question correctly, you're asking something like "How can I get the function which returned the given object instance?". So if this is what you asking then I think you can't. There probably are tricks to do that but none that I know or use. – lexicore Nov 07 '14 at 18:24