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散列中定义的类的方法。 只要知道这一点。