util.inherits – 替代或解决方法

我是一个n00b节点,并且findutil.inherits()非常有用,除了它似乎取代原始对象的整个原型的事实。 例如:

 var myClass = function(name){ this._name = name; }; myClass.prototype = { (...) }; util.inherits(myClass, require('events').EventEmitter); 

似乎抹去了我原来的原型。

这给我带来了两个不便:
1 – 我必须在调用inherits之后向我的原型声明添加属性,

 var myClass = function(name){ this._name = name; }; util.inherits(myClass, require('events').EventEmitter); myClass.prototype.prop1 = function(){...}; myClass.prototype.prop2 = function(){...}; 

最重要的是,我认为我不能从两个或更多不同的类inheritance。

任何人都可以向我解释为什么这是有道理的,什么是解决这个问题的好办法?

谢谢

从节点版本5.0.0开始, util.inherits已更改为支持使用setPrototypeOf方法查找的行为:

FirstBase.js

 function FirstBase(firstBaseProp){ this.firstBaseProp = firstBaseProp; } FirstBase.prototype.getFirstBaseProp = function(){ return this.firstBaseProp; }; module.exports = FirstBase; 

SecondBase.js

 var FirstBase = require('./FirstBase.js'), util = require('util'); function SecondBase(firstBaseProp, secondBaseProp){ this.secondBaseProp = secondBaseProp; SecondBase.super_.apply(this, arguments); } SecondBase.prototype.getSecondBaseProp = function(){ return this.secondBaseProp; }; util.inherits(SecondBase, FirstBase); module.exports = SecondBase; 

ThirdBase.js

 var SecondBase = require('./SecondBase.js'), util = require('util'); function ThirdBase(firstBaseProp, secondBaseProp, thirdBaseProp){ this.thirdBaseProp = thirdBaseProp; ThirdBase.super_.apply(this, arguments); } ThirdBase.prototype.getThirdBase = function(){ return this.thirdBaseProp; }; util.inherits(ThirdBase, SecondBase); module.exports = ThirdBase; 

instance.js

 var ThirdBase = require('./ThirdBase.js'); var instance = new ThirdBase('first', 'second', 'third'); // With node < 5.0.0 (Object.create) console.log(instance.getFirstBaseProp()); // first console.log(instance.getSecondBaseProp()); // undefined console.log(instance.getThirdBase()); // undefined // With node >= 5.0.0 (Object.setPrototypeOf) console.log(instance.getFirstBaseProp()); // first console.log(instance.getSecondBaseProp()); // second console.log(instance.getThirdBase()); // third 

如果您运行的是支持setPrototypeOf (0.12.x)的较旧版本的节点,则可以export util.inherits并将其用作内部实用程序函数。

util.inherits()后面声明你的原型是没有意义的。 我的猜测是util.inherits起源于一个仅供内部使用的方法,仅为最初打算使用的有限的内部使用情况而定制,这种使用情况在某些时候已经被发布以供一般性使用。 util模块是用纯JS编写的,所以很容易实现你自己的util.inherit版本来保存你的原型。 以下是原始的util.inherit源代码:

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

至于多重inheritance,这将是一个更难处理的问题,因为Javascript的原型inheritance并不真正适合多重inheritance。 每个实例只有一个内部[[Prototype]]属性,用于查找在实际实例中找不到的成员。 你可以将两个单独的“父类”的原型合并成一个原型,但是你将失去inheritance给他们的父母,你将失去改变父原型的能力,让所有的孩子都看到变化。

你应该先在函数定义之后inheritance,然后再实现你的对象。 另外不要忘记在你的类的构造函数中调用超类的构造函数。

 Function A(y){ this.y = x; } Function B(x,y){ this.x = x; A.call(this,y); } util.inherits(B,A); B.prototype.mythodA = function() { //do something } 

我非常想要同样的东西,并且对扩展不满意,所以我创build了这个扩展到已经有用的util.inherits方法:

 var util = require('util'); module.exports = { inherits : function(sub, sup, proto) { util.inherits(sub, sup); if (typeof proto !== 'undefined') { Object.keys(proto).forEach(function(key) { sub.prototype[key] = proto[key]; }); } } }; 

我把它放在我的项目的./util/index.js ,然后这样做来使用它:

 var EventEmitter = require('events').EventEmitter; var util = require('./util'); function Foo() { EventEmitter.call(this); } util.inherits(Foo, EventEmitter, { bar : function(){ console.log(this instanceof EventEmitter); // true } }); 

也许我会发布这个,如果我发现它的强大和有用的越来越多。 我自己几乎没有实现,所以我给它一个testing运行。

让我知道你的想法!

注意:这确实覆盖了最后一个在proto散列中定义的类的方法。 只要知道这一点。