Object.create(BaseObject) 和 util.inherits(MyObject, BaseObject) 有什么区别?

What is the difference between Object.create(BaseObject) and util.inherits(MyObject, BaseObject)?

这两种设置原型的方案有什么区别?

MyObject.prototype = Object.create(EventEmitter.prototype);

MyObject.prototype = util.inherits(MyObject, EventEmitter);

更新

是的,我在多个项目中看到它,他们将原型构造函数设置(恢复)为实际的对象构造函数,如下所示:

MyObject.prototype = Object.create(EventEmitter.prototype);
MyObject.prototype.constructor = MyObject;

构造函数"restoring"背后的原因是什么?我使用引号是因为这个动作对我来说更像是一个覆盖,因为 MyObject.prototypeEventEmitter 那么原型的构造函数应该是 EventEmitter 的构造函数。还原原型构造函数有什么好处?这解决了哪些现实生活问题?

其次,在 super_属性 中使用基本构造函数有什么好处?

util.inherits 在内部使用 Object.create 从 superclass 分配原型。如果您查看 inherits 方法的 source,您会发现它除了分配原型外几乎没有做其他事情:

exports.inherits = function(ctor, superCtor) {     
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
};
  1. 恢复原型对象上的 constructor 引用。这样

    MyObject.prototype.constructor === MyObject //true

    这是为了在javascript中实现classical OO继承。没有它,您将创建一个子 class,其构造函数将指向它的父 class。如果您正在创建一个模块并且如果有人试图访问您的 class 的构造函数,他们将错误地访问 parentClass 构造函数:

    MyObject.prototype = Object.create(EventEmitter.prototype);
    MyObject.prototype.constructor === MyObject ; //false
    (new MyObject).constructor === MyObject; //false
    
  2. 通过super_保存对superConstructor的引用属性为了方便:

    MyStream.super_ === EventEmitter; //true

    由于上一点提到的超级构造函数已被替换,如果您需要访问超级构造函数,可以使用此 属性 来实现。例如,您可以看到 fs.ReadStream:

    的继承链
    var ReadStream = require('fs').ReadStream;
    ReadStream.super_.super_.super_ // ReadStream<-Readable<-Stream<-EventEmitter