1

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.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
baalexander
  • 2,579
  • 1
  • 25
  • 32

3 Answers3

4

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.

Josh
  • 12,602
  • 2
  • 41
  • 47
0

I would recommend a different approach

// foo.js
var topic = require("topic");
topic.name = "History";
topic.emit("message");
topic.on("message", function() { /* ... */ });

// topic.js
var events = require("events");
var Topic = function() {

};

// inherit from eventEmitter
Topic.prototype = new events.EventEmitter();
exports.module = new Topic;

You have a good EventEmitter to do message passing for you. I recommend you just extend the prototype of Topic with it.

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • I changed my example to better reflect the basic inheritance I'm trying to achieve and how to use Object.create for that. The original Topic/Publish/Subscribe example was too confusing with node's concept of event emitting. – baalexander May 23 '11 at 15:26
0

Why not just use js native prototype based inheritance? Expose your constructor directly using module.exports:

//vehicle.js
module.exports = function() {
  //make this a vehicle somehow
}

Then:

// Pseudo code only. The final functions do not have to resemble this
var Vehicle = require('vehicle')
Vehicle.terrain = 'Land'
var car = new Vehicle()
// car and anotherCar will have unique Car-related values,
// but will use the same Vehicle info
var anotherCar = new Vehicle()
Tamzin Blake
  • 2,594
  • 20
  • 36
  • Nope. You just made all vehicles into land vehicles, not just the cars. – Matt DiMeo Mar 14 '13 at 22:47
  • The question didn't suggest that the vehicles aren't supposed to all be land vehicles. And for that matter, you're making a lot of assumptions about what Vehicle.terrain even does. – Tamzin Blake Apr 08 '13 at 16:26