1

我有一个模块车辆,其中包含一般车辆信息。我有另一个模块Car,它为Vehicle对象添加了更多的功能。如何使用Object.create继承node.js中的模块

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

我在使用Object.create的Car模块,但不知道Object.create调用应该去哪里。

  • 我应该在Car模块中有一个构造函数,它需要一个Vehicle对象的实例并以Vehicle实例为原型执行Object.create?
  • 还是应该Object.create发生在Vehicle对象的函数中,比如createCar?我的问题是,汽车应该关心它是从车辆派生出来的,汽车不应该知道汽车需要这样做。
  • 或即使Object.create是正确的方法。

请大家非常感谢任何示例和最佳实践。

更新:

我改变了例子,以更好地反映我试图解决继承问题。

回答

4

海事组织,你描述一个生成器模式而不是继承我想 - 我不会用的Object.create的这个。 VehicleBuilder负责构建具有与其相关的某些属性的对象。

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

它可能会使用类似:

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

如果你看看JS典型的遗传模式,它的一些更明确界定,并在节点使用两个主要模式。一个是util.inherits。它的代码很简单: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 } 
    }); 
}; 

,第二个是调用子类的构造函数的父类的构造。

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

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

因此,而不是车辆采取了一堆的属性或在其构造另一个对象,可以使用原型链和构造来定义自定义子类的行为。

+0

感谢您的样品。我结束了与util.inherits,但喜欢建设者的想法。 – baalexander 2011-05-28 04:16:31

0

我会建议不同的方法

// 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; 

你有一个很好的EventEmitter做消息传递给你。我建议你只用它来扩展Topic的原型。

+0

我改变了我的例子,以更好地反映我想要实现的基本继承以及如何使用Object.create。最初的主题/发布/订阅示例与节点的事件发射概念过于混淆。 – baalexander 2011-05-23 15:26:18

0

为什么不只是使用js本地原型为基础的继承?直接暴露你的构造使用module.exports:

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

然后:

// 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() 
+0

不是。你只是把所有的车辆变成了陆地车辆,而不仅仅是汽车。 – 2013-03-14 22:47:38

+0

这个问题并没有表明车辆不应该都是陆地车辆。就此而言,你对Vehicle.terrain甚至做了很多假设。 – 2013-04-08 16:26:26