我一直在努力理解为什么我一直在 Node 中看到这样的代码:
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)
The prototype of constructor will be set to a new object created from superConstructor.
As an additional convenience, superConstructor will be accessible through the constructor.super_ property.
由此我假设这意味着所有 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()
?我试着看 the documentation对于 Object.create
但我仍然感到困惑。让我试着看看我是否可以清楚地表达我认为正在发生的事情,你们可以纠正我:)
Object.create(proto [, propertiesObject ])
的第一个参数是您希望这个新对象拥有的原型(prototype)。我想这比定义构造函数并设置其 prototype
属性的经典方法更简单?第二个参数是一个带有属性的简单散列,应该添加到它将返回的新创建的对象中?所以,这...
var myInstance = Object.create(somePrototype, { someProp: someVal, someProp2: someVal2);
...而不是这个?
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
}
});
};
总结
新的 superCtor
不会消除在 MyStream
中执行 events.EventEmitter.call(this)
的需要吗?为什么让原型(prototype)相同然后在 MyStream
创建的实际实例上运行 EventEmitter
构造函数而不只是拥有 prototype< 为什么如此重要
是 EventEmitter
的实际实例吗?
此外,向ctor
的原型(prototype)添加constructor
属性的目的是什么?这是我不知道的 JavaScript 东西吗?
最佳答案
第一个 parent 可能需要参数。设置 Child.prototype 时,您正在定义对象,可能还没有准备好创建实例。
第二个父实例特定值 (this.someval) 放在子实例的原型(prototype)上,然后在所有子实例之间共享,或者当 Parent.apply(this,arguments) 在子主体中执行并隐藏它们时变得无用。
更多关于构造函数和原型(prototype)的信息:https://stackoverflow.com/a/16063711/1641941
关于javascript - 为什么要使用 Object.create?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21369432/