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

时间:2015-09-23 22:25:12

标签: javascript node.js prototype prototypal-inheritance

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

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_属性中使用基础构造函数有什么好处?

1 个答案:

答案 0 :(得分:1)

util.inherits在内部使用Object.create从超类中分配原型。如果您查看继承方法的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中实现经典的OO继承。如果没有它,您将创建一个子类,其构造函数将指向它的父类。如果您正在创建模块,并且有人试图访问您的类的构造函数,他们将错误地访问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