我是节点中的n00b,并且发现util.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(){...};
而且,最重要的是,我认为我不能从两个或更多不同的类继承。
任何人都可以向我解释为什么这有意义,以及解决这个问题的好方法是什么?
由于
答案 0 :(得分:12)
确实需要在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
}
});
};
至于多重继承,这将是一个更难解决的问题,因为Javascript的原型继承根本不适合多重继承。每个实例只有一个内部[[Prototype]]
属性,用于查找在实际实例中找不到的成员。你可以将两个独立的“父类”的原型合并到一个原型中,但是你将失去对他们的父母的继承,你将失去改变的能力父母原型,让所有孩子看到变化。
答案 1 :(得分:9)
您应该首先在函数定义之后继承,然后实现您的对象。另外,不要忘记在类的构造函数中调用超类构造函数。
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
}
答案 2 :(得分:4)
自节点版本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并将其用作内部实用程序功能。< / p>
答案 3 :(得分:2)
我非常想要同样的事情而且对扩展感到不满意,所以我为已经很有用的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
}
});
如果我发现它越来越强大且有用,我可能会发布这个。我自己几乎没有实现它,所以我给它一个测试运行。
让我知道你的想法!
注意:此执行覆盖任一类上的方法,其中包含末尾proto哈希中定义的方法。请注意这一点。
答案 4 :(得分:0)
Inherits-ex 库是浏览器友好的增强继承,完全兼容标准 node.js 继承,动态继承或创建。
isInheritedFrom(ctor, superCtor|superCtorName)
检查ctor是否继承自superCtormixin(ctor, superCtor|superCtor[])
混合SuperCtor的方法和属性:Clone(Copy) superCtor的所有属性(方法)到ctor。isMixinedFrom
createCtor
createObject
createFunction