Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sealed methods in javascript

Tags:

javascript

I am creating a slideshow that use Transition objects to transition slides:

function Transition(slide, settings){
    this.slide = slide;
    this.el = slide.el;
    this.settings = settings;
    this.duration = (this.settings['transitionSpeed'] / 1000) + 's';
    this.endAnimation = null;
}

Transition.prototype.inRight = function(callback){
    callback();
}

Transition.prototype.outRight = function(callback){
    callback();
}

Transition.prototype.inLeft = function(callback){
    callback();
}

Transition.prototype.outLeft = function(callback){
    callback();
}

Each of the methods correspond to how the slide should behave should it be transitioning in from the right, out to the right, in from the left, and out to the left. All well and good when the Transition is acting upon slides:

function ClassBasedTransition(slide, settings, transitionName){
    Transition.call(this, slide, settings);
    this.transitionName = transitionName;
}

ClassBasedTransition.prototype = Object.create(Transition.prototype);
ClassBasedTransition.prototype.constructor = ClassBasedTransition;

ClassBasedTransition.prototype.inRight = function(callback){
    var self = this;
    this.endAnimation = function(){
        DomUtil.removeClass(this, 'nd-' + self.transitionName + '-in-right-transition');
        callback();
        this.removeEventListener( 'webkitAnimationEnd', bound );
    }

    var bound = this.endAnimation;
    this.el.style.webkitAnimationDuration = this.duration;

    this.el.addEventListener( 'webkitAnimationEnd', bound);
    DomUtil.addClass(this.el, 'nd-' + this.transitionName + '-in-right-transition');
}

 **SNIP**

However, as I have been introducing 3D transitions, I am actually transitioning on the gallery container, and not individual slides, it makes less sense to have four transitions, and instead to only have two:

 //3 DIMENSIONAL TRANSITION
function D3Transition(slide, settings, transitionName){
    Transition.call(this, slide, settings);
    this.transitionName = transitionName;

    this.galleryEl = slide.gallery.el;
    if(!DomUtil.hasClass(this.galleryEl, 'nd-' + transitionName + '-gallery'))
        DomUtil.addClass(this.galleryEl, 'nd-' + transitionName + '-gallery');
}

D3Transition.prototype = Object.create(Transition.prototype);
D3Transition.prototype.constructor = D3Transition;

D3Transition.prototype.inRight = function(callback){
     **APPLY 3D EFFECT FORWARD**
}

D3Transition.prototype.inLeft = function(callback){
        **EFFECT 3D EFFECT IN REVERSE**
    }

D3Transition.prototype.outLeft = function(callback){
     **NO OP**
}

D3Transition.prototype.outRight = function(callback){
        **NO OP**
    }

Is there some way to seal D3Transition.prototype.outLeftand D3Transition.prototype.outRight so that derived objects cannot implement them? I know we can seal objects in javascript, is there some way to seal individual prototype functions?

like image 237
Mister Epic Avatar asked Nov 11 '22 10:11

Mister Epic


1 Answers

You can make a property not writable so it can't be modified by the inheriting class:

Object.defineProperty(D3Transition.prototype, 'outLeft', {
  value    : function(){},
  writable : false
});

Demo with two ways of doing it: http://jsbin.com/paqehera/1/edit

This solution prevents direct assignments to the outLeft property from having any effect both on the inheriting class prototype and on instances of either class. However, the solution is not perfect, because the property can be redefined on the prototype or instances using Object.defineProperty again (as mentioned in the comment by Benjamin Gruenbaum).

like image 110
Tibos Avatar answered Nov 14 '22 21:11

Tibos