设置原型的这两个解决方案有什么区别?
MyObject.prototype = Object.create(EventEmitter.prototype);
MyObject.prototype = util.inherits(MyObject, EventEmitter);
更新
是的,我在多个项目中看到它,他们将原型构造函数设置(恢复)到实际的对象构造函数,如下所示:
MyObject.prototype = Object.create(EventEmitter.prototype);
MyObject.prototype.constructor = MyObject;
"恢复"背后的原因是什么?构造函数?我使用引号,因为这个动作看起来更像是对我的覆盖,因为MyObject.prototype
是EventEmitter
,那么原型的构造函数应该是EventEmitter
的构造函数。恢复原型构造函数有什么好处?这解决了什么现实生活中的问题?
其次,在super_属性中使用基础构造函数有什么好处?
答案 0 :(得分:1)
util.inherits
在内部使用Object.create
从超类中分配原型。如果您查看继承方法的source,除了分配原型之外,您还会注意到其他一些事情:
exports.inherits = function(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
恢复原型对象的constructor
引用。这样
MyObject.prototype.constructor === MyObject //true
这是在javascript中实现经典的OO继承。如果没有它,您将创建一个子类,其构造函数将指向它的父类。如果您正在创建模块,并且有人试图访问您的类的构造函数,他们将错误地访问parentClass构造函数:
MyObject.prototype = Object.create(EventEmitter.prototype);
MyObject.prototype.constructor === MyObject ; //false
(new MyObject).constructor === MyObject; //false
为方便起见,通过super_
属性保存对superConstructor的引用:
MyStream.super_ === EventEmitter; //true
由于超级构造函数已被替换,如前所述,如果您需要访问超级构造函数,则可以使用此属性来执行此操作。例如,您可以看到fs.ReadStream
的继承链:
var ReadStream = require('fs').ReadStream;
ReadStream.super_.super_.super_ // ReadStream<-Readable<-Stream<-EventEmitter