17

I'm having a bit of trouble figuring out the best way to implement this.

I want a module that has a constructor that takes in an argument that stores it for later use within the module.

var ModuleB = function(moduleA) { this.moduleA = moduleA; } ModuleB.prototype = function() { //private stuff/functions function someMethod() { moduleA.doSomething(); } //public api return { someMethod : someMethod }; }(); 

In some other file

//ModuleA defined elsewhere var moduleA = new ModuleA(); //... var module = new ModuleB(moduleA); module.someMethod(); 

Now above in someMethod, moduleA is undefined, and this, is the global window object. Can someone explain how I would get access to moduleA? I don't understand what happens to this.moduleA = moduleA; after the constructor. I'm not really a javascript developer so if I'm using the wrong pattern here or something, feel free to chime in.

2
  • I updated the example to make it more clear Commented Aug 22, 2013 at 12:52
  • 1
    @Chase the only reason that fiddle works is because moduleA is global. Commented Aug 22, 2013 at 12:59

3 Answers 3

10

You are very close, but you're missing something important in your definition of someMethod.

EDIT: is is easier to tell what works and what doesn't if you change the name of the module property in ModuleB:

var ModuleA = function() {} ModuleA.prototype = (function () { return { someMethod: function () { return 'foo'; } }; }()); var ModuleB = function(moduleA) { this.innerModule = moduleA; } ModuleB.prototype = (function () { return { doStuff: function () { return this.innerModule.someMethod(); } }; }()); var moduleA = new ModuleA(); var moduleB = new ModuleB(moduleA); console.log(moduleB.doStuff()); // prints "foo" 

http://jsfiddle.net/mN8ae/1/

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

2 Comments

thank you for your example. In my real world situation the 'this' operator is not always the ModuleB object (idk, probably poor design by me I guess). Is there something I could change in this implementation to get it to work for those cases? Or would I be better off changing the areas that implement ModuleB. Example Here jsfiddle.net/QKZxh/1
functions on the prototype should always have this point to the calling object
1

Try this:

var ModuleB = function(moduleA) { this.moduleA = moduleA; } // Simplifying your code, what was missin is the "this" keyword accessing the moduleA ModuleB.prototype.someMethod = function() { this.moduleA.doSomething(); }; var module1 = new ModuleB({ doSomething: function(){ alert('i do something'); } }); module1.someMethod(); 

4 Comments

His prototype assignment is the return of an IIFE (an object), not a function.
Yes but, as soon as you created ModuleB it contains a "prototype". If you overwrite the entire object, all the magic reference to moduleA will get lost
moduleA is a property of each object instance, it has nothing to do with the prototype.
To expand on @jbabey, moduleA becomes a property of a given object when it is passed as a parameter.So, the javascript process sees ModuleA when passed as a parameter like. var ModuleB = function(moduleA) { var moduleA; this.moduleA = moduleA; }
0

You would need to use call/apply to execute the method for given context.

try this code (I have modified your code)

var ModuleB = function(moduleA) { this.moduleA = moduleA; }; ModuleB.prototype = function() { //private stuff/functions function someMethod() { this.doSomething(); } //public api return { someMethod : someMethod }; }(); var ModuleA=function(){ this.doSomething=function(){ alert('moduleA Method'); }; }; var modA=new ModuleA(); var modB=new ModuleB(modA); modB.someMethod.call(modA); 

Thanks!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.