util.inherits - 替代或解决方法

And*_*dez 19 javascript inheritance node.js

我是节点中的n00b,并且发现util.inherits()非常有用,除了它似乎替换了原始对象的整个原型.例如:

var myClass = function(name){
    this._name = name;  
};

myClass.prototype = {
    (...)
};

util.inherits(myClass, require('events').EventEmitter);
Run Code Online (Sandbox Code Playgroud)

似乎抹去了原来的原型.

这给我带来了两个不便之处:
1 - 我必须在调用后声明为我的原型添加属性inherits,

var myClass = function(name){
    this._name = name;  
};

util.inherits(myClass, require('events').EventEmitter);

myClass.prototype.prop1 = function(){...};
myClass.prototype.prop2 = function(){...};
Run Code Online (Sandbox Code Playgroud)

而且,最重要的是,我认为我不能从两个或更多不同的类继承.

任何人都可以向我解释为什么这是有道理的,什么是解决这个问题的好方法?

谢谢

lan*_*nzz 12

之后你必须申报你的原型是没有意义的util.inherits().我的猜测util.inherits起源于一种仅供内部使用的方法,仅针对最初用于的有限内部使用情况量身定制,在某些时候发布用于一般用途.该util模块是用纯JS编写的,因此很容易实现自己的版本util.inherit来保留原型.这是原始util.inherit来源:

exports.inherits = function(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
};
Run Code Online (Sandbox Code Playgroud)

至于多重继承,这将是一个更难解决的问题,因为Javascript的原型继承根本不适合多重继承.每个实例只有一个内部[[Prototype]]属性,用于查找在实际实例中找不到的成员.你可以两个独立的"父类"的原型合并成一个单一的原型,但随后你就失去了继承他们的父母,你会失去更改父原型,并拥有所有的孩子看到了变化的能力.


小智 9

您应该首先在函数定义之后继承,然后实现您的对象.另外,不要忘记在类的构造函数中调用超类构造函数.

Function A(y){
  this.y = x;
}

Function B(x,y){
  this.x = x;
  A.call(this,y);
}

util.inherits(B,A);

B.prototype.mythodA = function() {
    //do something
}
Run Code Online (Sandbox Code Playgroud)


Lif*_*ery 4

从节点版本 5.0.0 开始,util.inherits已更改为支持您使用setPrototypeOf方法寻找的行为:

FirstBase.js

function FirstBase(firstBaseProp){
    this.firstBaseProp = firstBaseProp;
}

FirstBase.prototype.getFirstBaseProp = function(){
    return this.firstBaseProp;
};


module.exports = FirstBase;
Run Code Online (Sandbox Code Playgroud)

SecondBase.js

var FirstBase = require('./FirstBase.js'),
    util = require('util');

function SecondBase(firstBaseProp, secondBaseProp){
    this.secondBaseProp = secondBaseProp;
    SecondBase.super_.apply(this, arguments);
}

SecondBase.prototype.getSecondBaseProp = function(){
    return this.secondBaseProp;
};

util.inherits(SecondBase, FirstBase);

module.exports = SecondBase;
Run Code Online (Sandbox Code Playgroud)

ThirdBase.js

var SecondBase = require('./SecondBase.js'),
    util = require('util');

function ThirdBase(firstBaseProp, secondBaseProp, thirdBaseProp){
    this.thirdBaseProp = thirdBaseProp;
    ThirdBase.super_.apply(this, arguments);
}

ThirdBase.prototype.getThirdBase = function(){
    return this.thirdBaseProp;
};

util.inherits(ThirdBase, SecondBase);

module.exports = ThirdBase;
Run Code Online (Sandbox Code Playgroud)

实例.js

var ThirdBase = require('./ThirdBase.js');

var instance = new ThirdBase('first', 'second', 'third');

// With node < 5.0.0 (Object.create)
console.log(instance.getFirstBaseProp()); // first
console.log(instance.getSecondBaseProp()); // undefined
console.log(instance.getThirdBase()); // undefined

// With node >= 5.0.0 (Object.setPrototypeOf)
console.log(instance.getFirstBaseProp()); // first
console.log(instance.getSecondBaseProp()); // second
console.log(instance.getThirdBase()); // third
Run Code Online (Sandbox Code Playgroud)

如果您运行的是支持的旧版本节点setPrototypeOf(0.12.x 支持),您可以只使用export util.inherits并将其用作内部实用程序函数。