And*_*dez 19 javascript inheritance node.js
我是节点中的n00b,并且发现util.inherits()非常有用,除了它似乎替换了原始对象的整个原型.例如:
var myClass = function(name){
this._name = name;
};
myClass.prototype = {
(...)
};
util.inherits(myClass, require('events').EventEmitter);
Run Code Online (Sandbox Code Playgroud)
似乎抹去了原来的原型.
这给我带来了两个不便之处:
1 - 我必须在调用后声明为我的原型添加属性inherits,
var myClass = function(name){
this._name = name;
};
util.inherits(myClass, require('events').EventEmitter);
myClass.prototype.prop1 = function(){...};
myClass.prototype.prop2 = function(){...};
Run Code Online (Sandbox Code Playgroud)
而且,最重要的是,我认为我不能从两个或更多不同的类继承.
任何人都可以向我解释为什么这是有道理的,什么是解决这个问题的好方法?
谢谢
lan*_*nzz 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
}
});
};
Run Code Online (Sandbox Code Playgroud)
至于多重继承,这将是一个更难解决的问题,因为Javascript的原型继承根本不适合多重继承.每个实例只有一个内部[[Prototype]]属性,用于查找在实际实例中找不到的成员.你可以两个独立的"父类"的原型合并成一个单一的原型,但随后你就失去了继承他们的父母,你会失去更改父原型,并拥有所有的孩子看到了变化的能力.
小智 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
}
Run Code Online (Sandbox Code Playgroud)
从节点版本 5.0.0 开始,util.inherits已更改为支持您使用setPrototypeOf方法寻找的行为:
FirstBase.js
function FirstBase(firstBaseProp){
this.firstBaseProp = firstBaseProp;
}
FirstBase.prototype.getFirstBaseProp = function(){
return this.firstBaseProp;
};
module.exports = FirstBase;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
实例.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
Run Code Online (Sandbox Code Playgroud)
如果您运行的是支持的旧版本节点setPrototypeOf(0.12.x 支持),您可以只使用export util.inherits并将其用作内部实用程序函数。