Object.create(BaseObject)和util的区别是什么?继承(MyObject BaseObject)

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

本文关键字:BaseObject 是什么 继承 MyObject 区别 util create Object      更新时间:2023-09-26

这两种解决方案设置原型的区别是什么?

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

是的,我在很多项目中看到他们设置(恢复)原型构造函数为实际对象构造函数,像这样:

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

"恢复"构造函数的原因是什么?我使用引号是因为这个动作对我来说更像是重写,因为MyObject.prototypeEventEmitter,那么原型的构造函数应该是EventEmitter的构造函数。恢复原型构造函数的优势是什么?这解决了什么现实生活中的问题?

其次,在super_属性中拥有基类构造函数的优势是什么?

util.inherits在内部使用Object.create从超类中分配prototype。如果你看一下inherits方法的源代码,你会注意到它除了分配prototype之外几乎没有做其他的事情:

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中实现经典的OO继承。如果没有它,您将创建一个子类,其构造函数将指向它的父类。如果你正在创建一个模块,如果有人试图访问你的类的构造函数,他们会错误地访问parentClass constructor:

    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