Setting the Prototype Constructor in JavaScript | John Papa

John Papa

Evangelist on the loose

Setting the Prototype Constructor in JavaScript

...

While writing the upcoming Part 2 of my Pluralsight course Building Apps with Angular and Breeze, I found myself wanting to extend a constructor object with another constructor’s members. I had an object called AbstractRepository that has a set of functions (ex: getAll, queryFailed) that could be shared by many repositories. I had a LookupRepository with its own functions that are very specific to getting “lookups”. The way I settled on was to extend the AbstractRepository‘s functions onto the LookupRepository by setting the prototype’s constructor. The result is that the LookupRepository gets all the functions that it has plus the AbstractRepository‘s functions too.

This technique is something Ward Bell and hashed out together during one of our code pairing sessions. It’s great what you can achieve when you work together! We adapted this from some ideas from this answer in StackOverflow.

First I create the constructor function for the LookupRepository.

// LookupRepository
function Ctor(mgr) {
    this.repoName = 'repository.lookup';
    this.entityName = 'lookups';
    this.manager = mgr;
    // Exposed data access functions
    this.getAll = getAll;
    this.setLookups = setLookups;
}

AbstractRepository.extend(Ctor);

return Ctor;

The AbstractRepository was injected into LookupRepository (using Angular‘s dependency injection). Notice I extend it by calling a method on the AbstractRepository and passing in the constructor function for the LookupRepository.

AbstractRepository.extend(Ctor);

The AbstractRepository‘s extend function set’s the prototype for the LookupRepository to the AbstractRepository‘s constructor function. This extends the AbstractRepository‘s functions to the LookupRepository. Then we make sure the LookupRepository gets back its constructor function. So now the LookupRepository will have the functions from both repositories.

// AbstractRepository
function Ctor() { }

Ctor.extend = function (repoCtor) {
    // Allow this repo to have access to 
    // the Abstract Repo's functions,
    // then put its own Ctor back on itself.
    repoCtor.prototype = new Ctor();
    repoCtor.prototype.constructor = repoCtor;
};

The AbstractRepository‘s function are now accessible from the LookupRepository. So if the AbstractRepository has some generic functions like _getAllLocal which may get all of the data for a given resource, then LookupRepository can use it.

// AbstractRepository
Ctor.prototype._getAllLocal = _getAllLocal;
Ctor.prototype._queryFailed = _queryFailed;

This adds value when you have a set of repositories such as LookupRepository, SessionRepository, SpeakerRepository, AttendeeRepository, and so on where they all can re-use the common functions from AbstractRepository.

I don’t need this technique often, but it does come in handy.

tags: javascript Prototype
  • iArouse

    Excellent course, really love it.

  • vintharas

    Isn’t this the normal use of protoypical inheritance in javascript? ( but for setting the prototype.constructor back that you should be able to omit) am I missing something ? :) love your courses btw!

    • johnpapa7

      Yes, it is an example of prototypical inheritance. Only more rare aspect is the use of the ctor setting back to itself.

      Thanks for the feedback and for watching the courses :)

      • vintharas

        Interesting! (read the stackoverflow thread now) I’ve never seen it used before like that, nice! Thx!

%d bloggers like this: