Super class access in JavaScript

The traditional way to access overridden functions in JavaScript is a bit kludgy.

For exaxmple, given you have a child class Child that inherits from a super class Parent you would do something like...

Child.prototype.validate = function() {

  // call base class method
  Parent.prototype.validate.call(this);

  // perform class specific overrides
};

This is in comparison to C# (or Javas or C++) where you might do something like...

public override void Validate()  
{
  // call base class method
  base.validate();

  // perform class specific overrides
}

So why the complexity in JavaScript? Well this has to do with JavaScript using prototypical inheritance. That whole discussion is out of scope for this article, but you can learn more on MDN.

super-prop

The mission at hand for me, was to create a simpler mechanism for accessing a super class' methods with similar syntax to C#, Java, or C++.

There are a number of inheritance tools that exist. However, I'm fine with using util.inherits in core Node and just wanted an additive mechanism for helping out with accessing methods up the prototype chain.

The end result is an NPM module called super-prop, which works by defining a new property on your instance that exposes the super class' method bound to your instance.

With it, you can do things like...

Child.prototype.validate = function() {

  // call base class method
  this.super.validate();

  // perform class specific overrides
};

To add this functionality to your class, you simply add a single line to the class constructor that will define the property.

function Child() {  
  // This will create a new property called 'super'
  // that can execute the parent methods bound to
  // the current instance
  superprop.define(this, Parent);
}

So how does it work? Well under the covers, it does exactly what you would do manually. At the time of this writing here is the factory method for the bound object.

/**
 * Creates an object containing methods
 * of the specificed proptotype that will be
 * bound to the supplied scope. This function
 * also creates a constructor property that is
 * a function call for the supplied prototype
 *
 * @api public
 * @param {Object} scope - the instance to 
 *  bind methos to
 * @param {Function} Type - the prototype
 *  of the super Type
 */
function create(scope, Type) {

  // make result the constructor
  var result = function() {
    Type.apply(scope, arguments);
  };

  // attach methods to result
  for(var key in Type.prototype) {
    if(typeof Type.prototype[key] === 'function') {
      result[key] = Type.prototype[key].bind(scope);
    }
  }

  return result;
}

For more details, check out the GitHub repository for super-prop.

comments powered by Disqus