19

我是一个n00b in node,发现util.inherits()非常有用,除了它似乎替换了原始对象的整个原型。例如:

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

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

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

似乎抹去了我原来的原型。

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

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

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

myClass.prototype.prop1 = function(){...};
myClass.prototype.prop2 = function(){...};

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

谁能向我解释为什么这是有道理的,以及解决这个问题的好方法是什么?

谢谢

4

5 回答 5

13

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

至于多重继承,这将是一个更难解决的问题,因为 Javascript 的原型继承根本不适合多重继承。每个实例只有一个内部[[Prototype]]属性,用于查找在实际实例中找不到的成员。您可以将两个单独的“父类”的原型合并为一个原型,但是您将失去对它们父类的继承,并且您将失去更改父原型并让所有子类看到更改的能力。

于 2012-11-20T14:04:32.653 回答
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
}
于 2013-04-11T16:30:32.177 回答
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;

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;

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;

实例.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

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

于 2016-02-10T16:37:21.570 回答
2

我非常想要同样的东西并且对扩展不满意,所以我为已经有用的util.inherits方法创建了这个扩展:

var util = require('util');

module.exports = {
    inherits : function(sub, sup, proto) {
        util.inherits(sub, sup);
        if (typeof proto !== 'undefined') {
            Object.keys(proto).forEach(function(key) {
                sub.prototype[key] = proto[key];
            });
        }
    }
};

我把它放在我的项目中./util/index.js,然后这样做来使用它:

var EventEmitter = require('events').EventEmitter;
var util = require('./util');

function Foo() {
    EventEmitter.call(this);
}

util.inherits(Foo, EventEmitter, {
    bar : function(){
        console.log(this instanceof EventEmitter); // true
    }
});

如果我发现它越来越强大和有用,也许我会发布它。我自己几乎没有实现它,所以我正在试运行它。

让我知道你的想法!

注意:这确实覆盖了任何一个类上的方法,最后在 proto 哈希中定义了这些方法。请注意这一点。

于 2013-05-21T04:04:42.993 回答
0

Inherits-ex库是一个浏览器友好的增强继承,与标准 node.js 完全兼容,具有动态继承或创建。

  • 静态继承
  • 多继承(继承链)支持
  • 随时继承——这是你想要的
    • 您不能在以标准方式继承之前声明方法/属性,因为它将替换原型对象。
  • 重复继承检查
  • Es6 类支持
  • 更多辅助功能
    • isInheritedFrom(ctor, superCtor|superCtorName)检查ctor是否继承自superCtor
    • mixin(ctor, superCtor|superCtor[])Mixin SuperCtor 的方法和属性: Clone(Copy) 所有 superCtor 的属性(方法)到 ctor。
    • isMixinedFrom
    • createCtor
    • createObject
    • createFunction
于 2021-04-16T10:22:56.927 回答