Javascript prototype - як працює прототипна спадкування в javascript

Що таке prototype (прототип)?

Прототип - це об'єкт, від якого успадковують св-ва інші об'єкти.

Будь-який об'єкт може бути прототипом?

У яких об'єктів є прототипи?

За замовчуванням, у будь-якого об'єкта є прототип. Прототип є об'єктом, тому він сам має прототип.

Стривай! Ще раз - що таке об'єкт?

Ти сказав, що у кожного об'єкта є прототип. Але якщо я напишу (<>) .prototype, то я отримаю undefined. У чому тут справа?

Так, ладно, але false примітивного типу, чому тоді false .__ proto__ повертає значення.

Отже, я хочу використовувати прототип для наслідування. Що потрібно зробити?

Давайте відразу домовимося, що ми не хочемо використовувати прототипи для наслідування властивостей одного об'єкта від іншого. Зрештою, це можна зробити простим додаванням властивостей до кінцевого об'єкту. Проте, якщо ми, наприклад, хочемо успадкувати всі властивості у якогось часто-використовуваного об'єкта, то ми можемо зробити щось на кшталт:

Справжня користь від використання прототипів з'являється тоді, коли безліч об'єктів успадковують один і той-же прототип. Тоді не потрібно піклуватися про копіюванні властивостей при кожному створенні об'єкта.

Ось тут якраз і використовується конструктор?

Так. Конструктор надає механізм привласнення загального прототипу створюваному об'єкту.

Перш ніж ти приведеш привер мені потрібно зрозуміти, чтоже означає властивість constructor.prototype?

Тому визначення таке. властивість функції prototype це об'єкт, який буде призначений в якості прототипу всіх об'єктах, створеним при використанні цієї функції в якості конструктора.

Тобто, властивість prototype об'єкта функції не є її прототипом:

Ось горезвісний приклад використання прототипів:

Круто! Значить якщо я зміню прототип конструктора, то все створені цим конструктором об'єкти зразу отримають ці зміни?

Вірно, але потрібно уточнити ... Якщо я зміню сам об'єкт-прототип, на який посилається властивість prototype функції, то відповідь - так. Це вірно бо __proto__ об'єкта посилається на той об'єкт, на який посилався prototype ф-ії під час створення цього об'єкта. Однак, якщо замінити його властивість prototype, присвоївши йому інший об'єкт, то, звичайно, вже створені об'єкти цих зміни не побачать. Їм вже не важливо, куди посилається св-во prototype.

Як виглядає прототип за замовчуванням?

Це об'єкт з єдиним св-м constructor, яке вказує на цю функцію:

Як працює оператор instanceof в прототипна спадкуванні?

Вираз a instanceof A означає, що св-во prototype (об'єкт, на який вона посилається), знаходиться в ланцюжку прототипів об'єкта a. Тобто, ми можемо легко обдурити instanceof (або себе?):

Що це взагалі таке - ланцюжок прототипів?

Кожен об'єкт має прототип, а цей прототип, будучи також об'єктом, теж має прототип. Ця послідовність прототипів і називається ланцюжком прототипів. У коні кожного ланцюжка завжди знаходиться прототип стандартного об'єкта Object. Ось у прототипу стандартного об'єкта прототипу вже не буде. Це єдиний виняток із загального правила:

Прототипна спадкування працює неявно. Коли у деякого об'єкта запраiівается св-во foo, воно спочатку перевіряється безпосередньо у цього об'єкта. Потім, якщо св-во не знайдено, воно шукається в прототипі об'єкта, і так далі поки св-во або не буде знайдено, або повернеться undefined.

Установка властивості об'єкта ніяк не впливає на прототип. Значення записується безпосередньо в даний об'єкт. Щоб змінити саме прототип, необхідно до нього звернутися явно.