Search code examples
node.jsinheritanceprototypal-inheritanceobject-create

How to use Object.create for inheritance within modules in node.js


I have a module Vehicle that contains general vehicle info. I have another module Car, which adds more functionality to Vehicle object.

// Pseudo code only. The final functions do not have to resemble this
var vehicle = require('vehicle')
vehicle.terrain = 'Land'
var car = vehicle.createCar()
// car and anotherCar will have unique Car-related values,
// but will use the same Vehicle info
var anotherCar = vehicle.createCar()

I am looking at using Object.create for the Car module, but not sure where the Object.create calls should go.

  • Should I have a constructor in the Car module that takes an instance of a Vehicle object and does an Object.create with the Vehicle instance as the prototype?
  • Or should the Object.create happen in a function on the Vehicle object, like createCar? My issue with this way, is Car should care that it's derived from Vehicle, Vehicle shouldn't know Car requires that.
  • Or even if Object.create is the right approach.

Please, any examples and best practices would be greatly appreciated.

Update:

I changed the example to better reflect the inheritance problem I'm trying to solve.


Solution

  • imo, you're describing a builder pattern rather than inheritance I think -- I wouldn't use object.create for this. A VehicleBuilder is responsible for constructing an object that has certain properties associated with it.

    var builder = new VehicleBuilder();
    builder.terrain = 'Land';
    builder.wheelCount = 2;
    builder.color = "blue";
    var motorcycle = builder.createVehicle();
    

    It might use something like:

    VehicleBuilder.prototype.createVehicle = function(){
        var me = this;
        return new Vehicle({
             color: me.color,
             terrain: me.terrain,
             wheelCount: me.wheelCount
        });
    }
    

    If you look at the typical inheritance pattern in js, its something much more well defined and uses two primary patterns in node. One is util.inherits. Its code is simple: https://github.com/joyent/node/blob/master/lib/util.js#L423-428

    exports.inherits = function(ctor, superCtor) {
      ctor.super_ = superCtor;
      ctor.prototype = Object.create(superCtor.prototype, {
        constructor: { value: ctor, enumerable: false }
      });
    };
    

    And the second is calling the parent constructor in the child class constructor.

    function ChildClass(){
        SuperClass.call(this); // here
    }
    

    Example: https://github.com/joyent/node/blob/master/lib/stream.js#L25-28

    So instead of a vehicle taking a bunch of properties or another object in its constructor, you use the prototype chain and the constructor to define custom subclass behavior.