прототип об’єкта

Сполучною ланкою виступає спеціальне властивість __proto__.

прототип proto

Якщо один об'єкт має спеціальну посилання __proto__ на інший об'єкт, то при читанні властивості з нього, якщо властивість відсутня в самому об'єкті, воно шукається в об'єкті __proto__.

Властивість __proto__ є у всіх браузерах, крім IE10-, а в більш старих IE воно, звичайно ж, теж є, але безпосередньо до нього не звернутися, потрібні трохи більше складні способи, які ми розглянемо пізніше.

Приклад коду (крім IE10-):

  1. Перший alert тут працює очевидним чином - він виводить властивість jumps об'єкта rabbit.
  2. Другий alert хоче вивести rabbit.eats. шукає його в самому об'єкті rabbit. не знаходить - і продовжує пошук в об'єкті rabbit .__ proto__. тобто, в даному випадку, в animal.

Ілюстрація того, що відбувається при читанні rabbit.eats (пошук йде від низу до верху):

прототип об'єкта

Також кажуть, що об'єкт rabbit «прототипна успадковує» від animal.

Звернемо увагу - прототип використовується виключно при читанні. Запис значення, наприклад, rabbit.eats = value або видалення delete rabbit.eats - працює безпосередньо з об'єктом.

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

Іншими словами, прототип - це «резервне сховище властивостей і методів» об'єкта, автоматично використовується при пошуку.

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

Подвійні квадратні дужки тут важливі, щоб не переплутати його з зовсім іншою властивістю, яке називається prototype. і яке ми розглянемо пізніше.

Звичайний цикл for..in не робить різниці між властивостями об'єкта і його прототипу.

Він перебирає все, наприклад:

Об'єкт, що створюється за допомогою Object.create (null) не має прототипу, а значить в ньому немає зайвих властивостей. Для колекції - як раз те, що треба.

Методи для роботи з proto

В сучасних браузерах є два додаткові методи для роботи з __proto__. Навіщо вони потрібні, якщо є __proto__. В общем-то, не дуже потрібні, але з історичних причин теж існують.

Читання: Object.getPrototypeOf (obj) Повертає obj .__ proto__ (крім IE8-) Запис: Object.setPrototypeOf (obj, proto) Встановлює obj .__ proto__ = proto (крім IE10-).

Крім того, є ще один допоміжний метод:

Створення об'єкта з прототипом: Object.create (proto, descriptors) Створює порожній об'єкт з __proto__. рівним першому аргументу (крім IE8-), другий необов'язковий аргумент може містити дескриптори властивостей.

Кілька прототипів одному об'єкту привласнити не можна, але можна організувати об'єкти в ланцюжок, коли один об'єкт посилається на інший за допомогою __proto__. той посилається на третій, і так далі.

В сучасних браузерах є методи для роботи з прототипом:

Можливо, вас бентежить недостатня підтримка __proto__ в старих IE. Але це не страшно. У наступних розділах ми розглянемо додаткові методи роботи з __proto__. включаючи ті, які працюють всюди.