Organize prototype javascript while perserving object reference and inheritance
You could make Controls
a class of it's own:
var Controls = function (controllable_object) {
this.ref = controllable_object;
};
Controls.prototype.next = function () {
this.ref.foo();
}
// ..
var Carousel = function () {
this.controls = new Controls(this);
};
// ..
This doesn't allow you to override the implementation of Controls
though. With more dependency injection you'd get something like:
var Controls = function (controllable_object) {
this.ref = controllable_object;
};
Controls.prototype.next = function () {
this.ref.foo();
}
// ..
var Carousel = function () {
this.controllers = [];
};
Carousel.prototype.addController = function (controller) {
this.controllers.push(controller);
};
// ..
var carousel = new Carousel();
carousel.addController(new Controls(carousel));
My inheritance is done like this:
$.extend(this.prototype , new parentClass);
Ouch. This is not inheritance (with new BigCarousel instanceof Carousel
), but just copying properties. Maybe this is enough for you, but then you should call it mixin. Also, you should avoid using new
for inheritance.
But this will cause the value of "this" being lost. How can I work around that?
It's impossible to have this
point to the parent object with nested properties (as long as you don't want to explicitly set it every time). You have only two choices:
- Forget it, and organize your methods by prefixing them (
controlNext
,controlBind
, …) -
Give each of your carousels its own
controls
object. For inheritance, make themCarouselControls
instances for example. This especially fits well if those controls are quite independent from the carousel, and don't need to access the carousel they're attached to everywhere. If they are not, you still can pass a reference to the parent carousel into their constructor for example:this.controls = new CarouselControls(this);
Also, for customizing the controls in different carousels, you might have to subclass the
CarouselControls
as well - or you prepare yourControls
object to serve for different carousels in general, so that fromBigCarousel
you canCarousel.call(this); // make this a carousel this.controls.activate({big: true, fast: false}); // or something