为什么我们应该使用Object.create?

我一直在试图理解为什么我总是在节点中看到像这样的代码:

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创build的新对象。

作为一个额外的便利,superConstructor将可以通过constructor.super_属性访问。

从那以后,我认为所有的util.inherits都是这样的:

 exports.inherits = function (constructor, superConstructor) { constructor.super_ = superConstructor; constructor.prototype = new superConstructor(); } 

似乎对我有意义,但后来我注意到在MyStream构造函数,他们调用event.EventEmitter.call(this); 这样EventEmitter构造函数MyStream在创build的MyStream的实例上运行。 我完全被这个困惑,因为constructor.prototype = new superConstructor(); 应该是所有需要的权利? 那么我去了源,发现了实际的function签名。

 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属性的经典方法更容易? 第二个参数是一个简单的哈希值,它应该被添加到新创build的对象中,它将返回? 所以这…

 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 } }); }; 

总结

new superCtor是否不需要在MyStream events.EventEmitter.call(this) ? 为什么如此重要,我们使原型相同,然后在MyStream正在创build的实际实例上运行EventEmitter构造函数,而不是仅仅将prototype作为EventEmitter的实际实例?

另外,为ctor的原型添加constructor的目的是什么? 这是一个我不知道的JavaScript的东西吗?

第一个父母可能需要参数。 设置Child.prototype时,您正在定义对象,可能尚未准备好创build实例。

第二个父实例特定的值(this.someval)放在子的原型上,然后在所有的子实例之间共享,或者当Parent.apply(this,arguments)在子体中执行并将其隐藏时变为无用的。

有关构造函数和原型的更多信息,请访问: https : //stackoverflow.com/a/16063711/1641941