Спочатку подивімося, чому останній код не працює.
Причина стає очевидною, якщо ми спробуємо його запустити. Конструктор класу, що успадковується, повинен викликати super(). Інакше "this" буде не визначене.
Виправлення:
class Rabbit extends Object {
constructor(name) {
*!*
super(); // потрібно викликати батьківський конструктор під час успадкування
*/!*
this.name = name;
}
}
let rabbit = new Rabbit("Rab");
alert( rabbit.hasOwnProperty('name') ); // trueАле це ще не все.
Навіть після виправлення все ще існує важлива різниця між "class Rabbit extends Object" та class Rabbit.
Як ми знаємо, синтаксис "extends" встановлює два прототипи:
- Між
"prototype"функцій-конструкторів (для методів). - Між самими функціями-конструкторами (для статичних методів).
У нашому випадку для class Rabbit extends Object це означає:
class Rabbit extends Object {}
alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) trueОтже, Rabbit тепер надає доступ до статичних методів Object через Rabbit, наприклад:
class Rabbit extends Object {}
*!*
// зазвичай ми викликаємо Object.getOwnPropertyNames
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b
*/!*Але якщо у нас немає extends Object, тоді для Rabbit.__proto__ не встановлено значення Object.
Приклад:
class Rabbit {}
alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) false (!)
alert( Rabbit.__proto__ === Function.prototype ); // як у будь-якої функції за замовчуванням
*!*
// помилка, такої функції в Rabbit немає
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error
*/!*Тому Rabbit не надає доступу до статичних методів Object у цьому випадку.
До речі, Function.prototype має "загальні" методи функції, такі як call, bind тощо. Вони в кінцевому підсумку доступні в обох випадках, тому що для вбудованого конструктора Object, Object.__proto__ === Function.prototype.
Приклад на картинці:
Коротко кажучи, є дві відмінності:
| class Rabbit | class Rabbit extends Object |
|---|---|
| -- | необхідно викликати super() в конструкторі |
Rabbit.__proto__ === Function.prototype |
Rabbit.__proto__ === Object |