Edit: Alex pointed out this example uses classical not prototypal inheritance as stated on John Resig’s blog.

Recently I’ve been introduced to Prototypal Inheritance thanks to Alex Sexton Using Inheritance to Organize Large jQuery Applications. I will attempt to give a short introduction to this concept. My understanding of the how is very limited. Fortunately, as I have found out, that doesn’t prevent me from using it!

Background, skip this if you know about Prototypal Inheritance JavaScript supports inheritance via the idea of a prototype. Everything in JavaScript is an object and every object has a prototype. You can inherit attributes from another object by pointing to it’s prototype. You can read about that in the above article or from many other great resources:

I wanted to go beyond a simple example and really implement this in a working application and explore the pros and cons of this methodology. Fortunately, Ben Nadel posted a fun little application to take apart. Read about it here. I would like to point out that I did not write this code, I am only borrowing it to show how to take some reasonably sophisticated JavaScript and refactor it for utilizing Inheritance.

I had a couple goals here. One, add Android support. Two, explore Inheritance. Now, I need to settle on a inheritance pattern. I chose to utilize John Resig’s Simple JavaScript Inheritance. Why? It is simple to understand and Alex’s method is a little over my pay grade.

So I create a super class, a class that other objects can use Classical-ly inherit from. This became the Touch Class:

var Touch = Class.extend({
    localPosition: '',
    lastPenPoint: '',
    position: '',
    init: function(event){
        var touch = (
            isIPhone ?
                window.event.targetTouches[ 0 ] :
                event
        )
        position =
            canvas.offset(),
        localPosition = {
            x: ( touch.pageX - position.left ),
            y: ( touch.pageY - position.top )
        },
        lastPenPoint = {
            x: localPosition.x,
            y: localPosition.y
        }
        return false;
    }
});

Previously, the position and penpoint were being calculated by a seperate function. I have added these to the init of the prototype. So everytime a new Touch class is constructed (keyword new), these fields are already populated. Now, we can rewrite onTouchStart and onTouchMove to extend this class and remove a lot of redundant code.

// I handle the touch start event. With this event,
// we will be starting a new line.
var onTouchStart = Touch.extend({
    init: function(event){
        this._super(event);  //inherit some common touch properties
        pen.beginPath();
        pen.moveTo( lastPenPoint.x, lastPenPoint.y );
        // Now that we have initiated a line, we need to
        // bind the touch/mouse event listeners.
        canvas.bind(
            (isTouch ? "touchmove" : "mousemove"),
            function(event){
                new onTouchMove(event)
            }
        );
        // Bind the touch/mouse end events so we know
        // when to end the line.
        canvas.bind(
            (isTouch ? "touchend" : "mouseup"),
            onTouchEnd
        );
                return false;  //prevent page from moving while drawing
    }
});
// I handle the touch move event. With this event, we
// will be drawing a line from the previous point to
// the current point.
    var onTouchMove = Touch.extend({
    init: function( event ){
        this._super( event );
        pen.lineTo( lastPenPoint.x, lastPenPoint.y );
        pen.stroke();
        return false;  //prevent page from moving while drawing
    }
});

The important part of these functions is that they call this._super( event ). When you create new onTouchStart/onTouchMove, they will run their own constructors but not the super classes (inheritance at work don’t want to run super class constructors unless they are needed). You will need to call super to run the super class’s constructor which is handling most of the heavy work of calculating mouse positions and whatnot.

Now, we have converted our function callbacks into classes. We need to create new instances of these classes to actually use them. References to the original functions will now be creating instances. You do this simply with:

new onTouchMove(event)

Then you are done, your constructor (init) will run and lines are drawn on the screen.

Comment below any tips for improving on this or questions about how it works.