Прежде всего, правило, согласно которому «конструктор Y должен содержать супер-вызов» , истинно только тогда, когда вы на самом деле определяете настраиваемый конструктор. Однако вы можете определить Y
без явного конструктора.
Как вы увидите, X.prototype
- это instanceof X
, а Y.prototype
- instanceof Y
. Определяя конструктор («класс»), вы всегда неявно создаете объект-прототип (fre sh), для которого свойство constructor
установлено на этот конструктор. Итак, очевидно, X.prototype != Y.prototype
.
Но, поднявшись на один уровень вверх в цепочке прототипов, вы сразу же обнаружите Object.prototype
, что означает, что цепочки прототипов для экземпляров X
и Y
немедленно сливаются. Все следующие отпечатки «верны»:
class X {}
class Y extends Object {}
console.log(Object.getPrototypeOf(X.prototype) === Object.prototype);
console.log(Object.getPrototypeOf(Y.prototype) === Object.prototype);
console.log(Object.getPrototypeOf(X.prototype).constructor === Object);
console.log(Object.getPrototypeOf(Y.prototype).constructor === Object);
Остается различие в цепочке прототипов конструкторов (то есть не построенных объектов или объектов-прототипов, а самих функциональных объектов) ; в цепочке Y
есть дополнительный уровень, который представляет Object
. Опять же, все это печатает "true":
class X {}
class Y extends Object {}
console.log(Object.getPrototypeOf(X) === Function.prototype);
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Y)) === Function.prototype);
console.log(Object.getPrototypeOf(Y) === Object); // Object is missing in the proto chain of X