Коротка відповідь: __proto__
це посилання на prototype
властивість конструктора, який створив об'єкт.
Об'єкти в JavaScript
Об'єкт JavaScript - це вбудований тип для колекції нульових або більше властивостей. Властивості - це контейнери, що містять інші об'єкти, примітивні значення або функції.
Конструктори в JavaScript
Функції - це звичайні об'єкти (які реалізуються [[Call]]
в термінах ECMA-262) з додатковою можливістю дзвінка, але грають іншу роль у JavaScript: вони стають конструкторами ( фабриками для об'єктів), якщо викликати черезnew
оператора. Таким чином, конструктори є грубим аналогом класів іншими мовами.
Кожна функція JavaScript - це фактичний екземпляр Function
вбудованого функціонального об'єкта, який має спеціальне властивість, іменоване prototype
для втілення в основу прототипу успадкування та спільних властивостей. Кожен об'єкт, створений функцією конструктора, має неявну посилання (називається прототипом або __proto__
) на значення його конструктора prototype
.
Конструктор prototype
- це свого роду план будівельних об'єктів, оскільки кожен об'єкт, створений конструктором, успадковує посилання на нього prototype
.
Прототип ланцюга
Об'єкт вказує свій прототип через внутрішню властивість [[Prototype]]
або __proto__
. Зв'язок прототипу між двома об'єктами стосується спадкування: кожен об'єкт може мати ще один об'єкт як свій прототип. Прототипом може бути null
значення.
Ланцюжок об'єктів, з'єднаних __proto__
властивістю, називається ланцюгом прототипу . Коли посилання робиться на властивість об’єкта, це посилання є на властивість, що зустрічається в першому об'єкті ланцюга прототипу, що містить властивість цього імені. Ланцюг прототипу поводиться так, ніби це єдиний об'єкт.
Дивіться це зображення (витягнуте з цього блогу ):
Щоразу, коли ви намагаєтеся отримати доступ до властивості в об'єкті, JavaScript починає пошук його в цьому об’єкті і продовжує його прототип, прототип прототипу тощо, поки не з'явиться властивість або якщо воно не __proto__
містить значення null
.
Цей тип успадкування за допомогою ланцюга прототипу часто називають делегуванням, щоб уникнути плутанини з іншими мовами за допомогою ланцюга класів.
Практично всі об'єкти є екземплярами Object
, тому що Object.prototype
він останній у ланцюзі прототипу. Але Object.prototype
це не екземпляр, Object
оскільки він Object.prototype.__proto__
містить значення null
.
Ви також можете створити об'єкт з таким null
прототипом:
var dict = Object.create(null);
Такий об'єкт є краще картою (словник) , ніж буквальний об'єкт, тому цей зразок іноді називають диктує патерном ( диктує для словника).
Примітка: буквальні об'єкти, створені за допомогою, {}
є екземплярами, Object
оскільки ({}).__proto__
є посиланням на Object.prototype
.