2013-08-22 23 views
16

Mam problem z ustaleniem najlepszego sposobu realizacji tego.Odsłaniając wzorzec modułu z konstruktorem

Chcę moduł, który ma konstruktora, który przyjmuje argument, który przechowuje go do późniejszego wykorzystania w module.

var ModuleB = function(moduleA) { 
    this.moduleA = moduleA; 
} 

ModuleB.prototype = function() { 
    //private stuff/functions 
    function someMethod() { 
     moduleA.doSomething(); 
    } 

    //public api 
    return { 
     someMethod : someMethod 
    }; 
}(); 

w jakiś inny plik

//ModuleA defined elsewhere 
var moduleA = new ModuleA(); 

//... 

var module = new ModuleB(moduleA); 
module.someMethod(); 

Teraz powyżej w someMethod, moduleA jest niezdefiniowana, a this, to globalny okno przedmiot. Czy ktoś może wyjaśnić, w jaki sposób uzyskać dostęp do modułu A? Nie rozumiem, co stanie się z this.moduleA = moduleA; po konstruktorze. Nie jestem programista javascript więc jeśli używam niewłaściwego wzorca tutaj lub coś, nie krępuj się kurant

+0

Zaktualizowałem przykład, aby było bardziej zrozumiałe. –

+1

@Chase Jedynym powodem, dla którego fiddle działa, jest to, że 'moduleA' jest globalne. – jbabey

Odpowiedz

10

Jesteś bardzo blisko, ale jesteś brakuje czegoś ważnego w twojej definicji someMethod.

EDIT: jest to łatwiej powiedzieć, co działa, a co nie, jeśli zmienić nazwę właściwości modułu w 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/

+0

dziękuję za twój przykład. W mojej rzeczywistej sytuacji operatorem "tego" nie zawsze jest obiekt ModuleB (idk, prawdopodobnie źle zaprojektowany przeze mnie, jak sądzę). Czy jest coś, co mógłbym zmienić w tej implementacji, aby działało w tych przypadkach? A może lepiej byłoby zmienić obszary implementujące ModuleB. Przykład Tutaj http://jsfiddle.net/QKZxh/1/ –

+2

funkcje na prototypie powinny zawsze mieć "this" wskazywać obiekt wywołujący – jbabey

1

Spróbuj tego:.

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(); 
+1

Jego prototypowe zadanie polega na zwrocie IIFE (obiektu), a nie funkcji. – jbabey

+0

Tak, ale zaraz po utworzeniu ModuleB zawiera on "prototyp". Jeśli nadpiszesz cały obiekt, wszystkie magiczne odniesienia do modułu A zostaną zgubione –

+0

'moduleA' jest właściwością każdej instancji obiektu, nie ma nic wspólnego z prototypem. – jbabey

0

będzie musiał użyć połączenia/zastosowanie wykonać metodę dla danego kontekstu.

spróbuj tego kodu (Mam zmodyfikowany kod)

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); 

Dzięki!

Powiązane problemy