__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.