Вы должны использовать стиль наследования __proto__
. Предполагается, что вы пишете только для Node или поддерживаете только свои любимые браузеры .Кроме того, Base.call(this)
необходимо, если вы заботитесь о какой-либо логике в конструкторе базового прототипа.
Метод __proto__
для ссылки на базовый прототип гарантирует, что оператор instanceof
правильно идентифицирует экземплярыпрототип.Свойство .constructor
экземпляров дочернего элемента class будет ссылаться на ожидаемый конструктор.Это также имеет то преимущество, что не создает экземпляр нового экземпляра базового прототипа.
Стиль new Base()
также гарантирует, что instanceof
даст вам правильный ответ, но он запустит конструктор для Base.Обычно это не проблема, но может быть проблематично, если ваш базовый конструктор имеет требуемые аргументы.Также будет установлено свойство .constructor
для базового конструктора, не для конструктора-потомка .
Установка прототипа вашего класса на прототип базовой class будет путать 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.