5

で遊んでいますEventEmitterが、モジュールからどのように実装する必要があるかについて混乱しています。私はいくつかの異なる方法を見てきましたが、それらはすべて機能しているようです。ここに私が見たいくつかがあります:

ここから:

var Twitter = function() {...};

Twitter.prototype = new events.EventEmitter;

しかし、「Mastering Node」では、次のようにします。

function Dog(name) {
  this.name = name;
  EventEmitter.call(this);
}

Dog.prototype.__proto__ = EventEmitter.prototype;

(なぜ .call が必要なのですか?)

そして、自分のコードでさらに別の方法を試しました:

function Class() {}

Class.prototype = EventEmitter.prototype;

それらはすべて EventEmitter から独自の方法で継承しているだけなので、最も単純なソリューションが最適ではないでしょうか?

4

2 に答える 2

20

ノードにはライブラリ関数 util.inherits があり、受け入れられている回答よりも少し簡単です。以下のコードは、v0.8.12 ドキュメントから変更されています。

var util = require("util");
var events = require("events");

function MyStream() {
  events.EventEmitter.call(this);
}

util.inherits(MyStream, events.EventEmitter);
于 2012-10-14T02:35:03.457 に答える
18

__proto__継承のスタイルを使用する必要があります。これは、Node専用にコーディングしているか、お気に入りのブラウザのみをサポートしていることを前提としています。また、Base.call(this)ベースプロトタイプのコンストラクターのロジックを気にする場合にも必要です。

基本プロトタイプを参照する__proto__手法により、instanceofオペレーターはプロトタイプのインスタンスを正しく識別できます。.constructorクラスのインスタンスのプロパティは、期待するコンストラクターを参照します。また、ベースプロトタイプの新しいインスタンスをインスタンス化しないという利点もあります。

このスタイルは、それが正しい答えnew Base()を与えることも保証しますが、Baseのコンストラクターを実行します。instanceof通常は問題になりませんが、ベースコンストラクターに引数が必要な場合は問題になる可能性があります。また、プロパティを子孫コンストラクターではなく、.constructor基本コンストラクターに設定します。

クラスのプロトタイプを基本クラスのプロトタイプに設定すると、基本instanceofの子孫も子のインスタンスであるように見えるため、混乱します。

泥のように澄んでいますよね?この例は役立つはずです:

// Base constructor.
// A, B, and C will inherit from Base.
function Base() {
    this.name = 'base';
}

// new Base() style
function A() {
    Base.call(this);
}
A.prototype = new Base();

// __proto__ = prototype style
function B() {
    Base.call(this);
}
B.prototype.__proto__ = Base.prototype;

// prototype = protoype style
function C() {
    Base.call(this);
}
C.prototype = Base.prototype;

// create instances
var a = new A();
var b = new B();
var c = new C();

// are we who we think we are?
console.assert(a instanceof A);
console.assert(b instanceof B);
console.assert(c instanceof C);
// so far so good

// do we respect our elders?
console.assert(a instanceof Base);
console.assert(b instanceof Base);
console.assert(c instanceof Base);
// we have respect

// test to see that Base.call(this)
// functioned as expected
console.assert(a.name == 'base');
console.assert(b.name == 'base');
console.assert(c.name == 'base');
// ok, good...

// but now things get weird
console.assert(a instanceof C);
console.assert(b instanceof C);
// that's not right! a is not C, b is not C!

// At least A and B do not confuse identities
console.assert(!(a instanceof B));
console.assert(!(b instanceof A));

console.assert(!(c instanceof A));
console.assert(!(c instanceof B));

// so we've determined that style C is no good.
// C confuses the inheritance chain.

// B is the winner.

// Why? Only B passes this test
console.assert(b.constructor == B);

// a and c's constructors actually point to the Base constructor
console.assert(a.constructor == Base);
console.assert(c.constructor == Base);

// Word B.
于 2011-08-02T03:50:07.093 に答える