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.

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the samples. I ended up going with util.inherits, but like the idea of a builder.
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.

1 Comment

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.
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()

2 Comments

Nope. You just made all vehicles into land vehicles, not just the cars.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.