如何在Node.JS中实现inheritance

我们如何在Node.JS中使用“inheritance”? 我听说原型和java中的接口类似。 但我不知道如何使用它!

尽pipe在JavaScript中执行inheritance和OO有很多种方法,但在Node.js中,通常会使用内置的util.inherits函数来创build从另一个inheritance的构造函数。

请参阅http://book.mixu.net/ch6.html关于此主题的良好讨论。

例如:

var util = require("util"); var events = require("events"); function MyOwnClass() { // ... your code. } util.inherits(MyOwnClass, events.EventEmitter); 

在纯JS中创build对象构造函数:

他们只是像任何其他的JS函数的function,但调用新的关键字。

 function Constructor(){ //constructors are typically capitalized this.public = function(){ alert(private); } var private = "Untouchable outside of this func scope."; } Constructor.static = function(){ alert('Callable as "Constructor.static()"'); } var instance = new Constructor(); 

遗产:

 function SubConstructor(){ this.anotherMethod(){ alert('nothing special'); } } function SubConstructor.prototype = new Constructor(); var instance = new SubConstructor(); instance.public(); //alerts that private string 

关键的区别是原型inheritance来自对象,而不是构build它们的东西。

一个缺点是,没有很好的方法来编写一些可以像private一样inheritance实例variables的东西。

然而,巨大的巨大优势是,我们可以在不影响超级构造函数的情况下混淆原型,甚至在构build完成之后,也可以为每个对象更改方法或属性。 在较高级别的代码中这很less在实践中完成,因为它会造成非常令人困惑的API,但是对于那些你可能希望跨越一组实例共享一个变化的值而不用仅仅做出它全球。

我们得到这个实例化后的行为的原因是因为JSinheritance实际上是在查找过程中进行的,在这个过程中,任何方法调用都会在实例链及其构造函数原型属性上运行,直到find调用或者退出的方法。 这实际上可以变慢,如果你绝对疯狂的级联inheritance(这被广泛认为是一种反模式)。

实际上,我并没有专门针对inheritacne打自己的原型,而是倾向于通过更复杂的方法构build对象,但是在需要时它非常方便,并且提供了很多不太明显的效用。 例如,如果只有一个属性不同的对象对您有用,但您不想触摸原始对象。

 var originInstance = { originValue:'only on origin', theOneProperty:'that would make this old object useful if it were different' } function Pseudoclone(){ this.theOneProperty = "which is now this value"; } Pseudoclone.prototype = originInstance; var newInstance = new Psuedoclone(); //accesses originInstance.originValue but its own theOneProperty 

有更多的现代便利方法,如Object.create,但只有函数构造函数给你的选项来封装私人/实例variables,所以我倾向于支持他们,因为10次任何东西不要求封装只是一个对象字面量。

覆盖和调用对象顺序:

 ( function Constructor(){ var private = "public referencing private"; this.myMethod = function(){ alert(private); } } ).prototype = { myMethod:function(){ alert('prototype'); }; var instance = new Constructor(); instance.myMethod = function(){ alert(private); } instance.myMethod();//"undefined" 

注意:构造器周围的parens允许在一个点上定义和评估它,所以我可以像在同一行上的一个对象一样对待它。

myMethod警告“未定义”,因为外部覆盖的方法是在构造函数的闭包之外定义的,这是有效的使内部variables类似私有的。 所以你可以replace这个方法,但是你不能访问它的function。

现在我们来做一些评论。

 ( function Constructor(){ var private = "public referencing private"; this.myMethod = function(){ alert(private); } } ).prototype = { myMethod:function(){ alert('prototype'); }; var instance = new Constructor(); //instance.myMethod = function(){ alert(private); } instance.myMethod();//"public referencing private" 

和…

 ( function Constructor(){ var private = "public referencing private"; //this.myMethod = function(){ alert(private); } } ).prototype = { myMethod:function(){ alert('prototype'); }; var instance = new Constructor(); //instance.myMethod = function(){ alert(private); } instance.myMethod();//"prototype" 

请注意,出于同样的原因,原型方法也无法访问该内部私有variables。 这是关于是否在构造函数中定义了一些东西。 注意,传递给构造函数的参数也将是私有的实例variables,这些variables可以方便地执行,比如覆盖一组默认选项。

情侣更多的细节

实际上没有必要使用parens来调用新的时候,除非你有必要的参数,但我倾向于把它们放在习惯之外(它的作用是把它们看作是激发的函数,然后留下代表该激发的范围的对象)并且认为它不会比new Constructor;更像Java开发者new Constructor;

此外,任何需要params的构造函数,我喜欢在内部添加默认值,如:

 var param = param || ''; 

通过这种方式,您可以将构造函数传递给像util.inherit这样的便捷方法,而不需要为您定义值。

Params也是有效的私有持久实例variables,就像在构造函数中定义的任何variables一样。

哦,对象文字(用{ key:'value' }定义的对象)可能是最好的想法,大致相当于这个:

 var instance = new Object(); instance.key = 'value'; 

在Coffeescript的帮助下,我们可以轻松实现。

例如:扩展一个类:

 class Animal constructor: (@name) -> alive: -> false class Parrot extends Animal constructor: -> super("Parrot") dead: -> not @alive() 

静态属性:

 class Animal @find: (name) -> Animal.find("Parrot") 

实例属性:

 class Animal price: 5 sell: (customer) -> animal = new Animal animal.sell(new Customer) 

我只是拿CoffeeScript中的示例代码类 。 您可以在其官方网站上了解更多有关CoffeeScript的信息: http : //coffeescript.org/