我一直在试图理解为什么我总是在节点中看到这样的代码:
var util = require("util");
var events = require("events");
function MyStream() {
events.EventEmitter.call(this);
}
util.inherits(MyStream, events.EventEmitter);
MyStream.prototype.write = function(data) {
this.emit("data", data);
}
为了更好地理解,我去看了文档。
util.inherits(constructor, superConstructor)
构造函数的原型将被设置为从superConstructor创建的新对象。 作为一种额外的方便,superConstructor可以通过constructor.super_属性访问。
由此,我认为这意味着util.inherits
所做的一切是:
exports.inherits = function (constructor, superConstructor) {
constructor.super_ = superConstructor;
constructor.prototype = new superConstructor();
}
对我来说似乎很有意义,但后来我注意到,在MyStream
构造函数中,它们调用了event.EventEmitter.call(this);
,这样EventEmitter
构造函数就可以在正在创建的MyStream
实例上运行。我对此完全感到困惑,因为constructor.prototype = new superConstructor();
应该是它所需要的全部,对吧?我去了源找到了实际的函数签名。
exports.inherits = function(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
一旦我看到这一点,我就完全糊涂了,因为我想弄清楚Object.create
在这里做什么。为什么它要这样做而不是只做new superCtor()
呢?我试着查看文献资料的Object.create
,但我仍然很困惑。让我试着看看我是否能说出我认为正在发生的事情,你们可以纠正我:)
Object.create(proto [, propertiesObject ])
的第一个参数是您希望这个新对象具有的原型。我想这比定义构造函数和设置其prototype
属性的传统方法简单吗?第二个参数是带有属性的简单散列,应该添加到它将返回的新创建的对象中?所以这个..。
var myInstance = Object.create(somePrototype, { someProp: someVal, someProp2: someVal2);
这个的...instead?
function MyClass () {
this.prop = someVal;
this.prop2 = someVal2;
// etc
}
MyClass.prototype = somePrototype;
var myInstance = new MyClass();
我不确定我对Object.create
的理解是否完全准确,所以希望你们能澄清。假设我现在了解Object.create
,那么为什么util.inherits
函数不像这样呢?
exports.inherits = function(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(new superCtor, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
总结
new superCtor
难道不会消除在MyStream
中执行events.EventEmitter.call(this)
的需要吗?为什么我们要使原型相同,然后在MyStream
正在创建的实际实例上运行MyStream
构造函数,而不是让prototype
成为EventEmitter
的一个实际实例?
另外,将constructor
属性添加到ctor
的原型中的目的是什么?这是我不知道的JavaScript特性吗?
发布于 2014-01-26 16:17:31
第一个家长可能需要参数。在设置Child.prototype时,您正在定义对象,可能还没有准备好创建实例。
第二个父实例特定值(this.someval)放在子实例的原型上,然后在所有子实例之间共享,或者当Parent.apply(这个,参数)在子实例的体内执行并隐藏它们时变得无用。
关于构造函数和原型的更多信息,在这里:https://stackoverflow.com/a/16063711/1641941
https://stackoverflow.com/questions/21369432
复制