Skip to content

Latest commit

 

History

History
81 lines (55 loc) · 3.2 KB

File metadata and controls

81 lines (55 loc) · 3.2 KB

Спочатку подивімося, чому останній код не працює.

Причина стає очевидною, якщо ми спробуємо його запустити. Конструктор класу, що успадковується, повинен викликати 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" встановлює два прототипи:

  1. Між "prototype" функцій-конструкторів (для методів).
  2. Між самими функціями-конструкторами (для статичних методів).

У нашому випадку для 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