I got a RequireJs module which instances another module and proxies some methods of it. I would now like to hide the module instance itself and only allow access through the proxy-methods.
define(['mediator'], function(Mediator) {
var Proxy;
Proxy = function(prefix) {
this.prefix = prefix;
this.mediator = new Mediator();
};
Proxy.prototype.on = function(event, callback, context) {
this.mediator.subscribe(this.prefix + event, callback, context || this);
};
Proxy.prototype.off = function(event, callback, context) {
this.mediator.unsubscribe(this.prefix + event, callback, context || this);
};
Proxy.prototype.trigger = function() {
arguments[0] = this.prefix + arguments[0];
this.mediator.trigger.apply(this.mediator, arguments);
};
return Proxy;
});
require(['proxy'], function(Proxy) {
var proxy = new Proxy('sample:');
// this access is secured and bound to the prefix
// I cannot mess up with other events which do not belong to me
proxy.on('log', function(message) { console.log(message); });
proxy.trigger('log', 'hi hello');
// unfortunately there still would be a hack to leave my event scope
proxy.mediator.trigger('outerscope:test', 'blabla');
});
As you see it would be possible to access the internal used mediator object of the proxy prototype and to mess up with it...
I would now like to hide the mediator instance somehow but have no idea where. I could store it in some normal variable inside the requirejs module callback but this would not work good with requirejs and could cause overlapping.
So what else can I do?
UPDATE:
define(['mediator'], function(Mediator) {
var Proxy;
var mediator = new Mediator();
Proxy = function(prefix) {
this.prefix = prefix;
};
Proxy.prototype.on = function(event, callback, context) {
mediator.subscribe(this.prefix + event, callback, context || this);
};
Proxy.prototype.off = function(event, callback, context) {
mediator.unsubscribe(this.prefix + event, callback, context || this);
};
Proxy.prototype.trigger = function() {
arguments[0] = this.prefix + arguments[0];
mediator.trigger.apply(this.mediator, arguments);
};
return Proxy;
});
require(['proxy'], function(Proxy) {
var proxy = new Proxy('sample:');
proxy.on('log', function(message) { console.log(message); });
});
This is a typical example of encapsulation of variable within closures in Javascript. What you need is to define you mediator instance as a local variable in the same scope with the Proxy
. This will allow the Proxy objects to have access to Mediator
via closure but will isolate Mediator from the code outside your define-callback. So like this:
define(['mediator'], function(Mediator) {
// Make mediator local scope variable
var mediator = new Mediator(),
Proxy = function(prefix) {
this.prefix = prefix;
};
Proxy.prototype.on = function(event, callback, context) {
mediator.subscribe(this.prefix + event, callback, context || this);
};
// ... rest of the code
return Proxy;
});