Skip to main content

Чим __proto__ відрізняється від prototype?

Коротко

ВластивістьДе знаходитьсяЩо зберігає
__proto__У об'єктаПосилання на його прототип
prototypeУ функції-конструктора або класуОб'єкт, який стане прототипом для створюваних об'єктів
  • __proto__вже створеного об'єкта
  • prototypeу конструктора (шаблону), за яким створюються об'єкти

Приклад для розуміння

javascript
function User(name) { this.name = name; } User.prototype.sayHi = function() { console.log(`Привіт, ${this.name}`); }; const tim = new User('Tim');

Тепер подивимось, що відбувається:

javascript
console.log(tim.__proto__ === User.prototype); // true console.log(User.prototype.constructor === User); // true

Розшифровка:

  1. User.prototype - це об'єкт, який містить методи (sayHi) і слугує прототипом для всіх об'єктів, створених через new User().
  2. tim.__proto__ - це посилання на той самий об'єкт User.prototype.

Візуально

javascript
User (function) ├── prototype ──► { sayHi(), constructor: User } └── new User('Tim') → tim { name: 'Tim', __proto__: User.prototype }

Тобто __proto__ створеного об'єкта → вказує на prototype функції, яка його створила.


Простими словами

ВластивістьПро що кажеПриклад
prototype"Що отримають мої діти"User.prototype.sayHi = ...
__proto__"Хто мій батько"tim.__proto__ === User.prototype

Приклад з ланцюжком

javascript
function Animal() {} Animal.prototype.eats = true; function Dog() {} Dog.prototype = Object.create(Animal.prototype); Dog.prototype.barks = true; const rex = new Dog(); console.log(rex.barks); // true (в Dog.prototype) console.log(rex.eats); // true (в Animal.prototype)

Ланцюжок виглядає так:

javascript
rex.__proto__Dog.prototypeAnimal.prototypeObject.prototypenull

У всіх об'єктів є __proto__,

а prototype є тільки у функцій і класів

javascript
const obj = {}; console.log(obj.__proto__); // Object.prototype console.log(obj.prototype); // undefined function Foo() {} console.log(Foo.prototype); // { constructor: Foo } console.log(Foo.__proto__); // Function.prototype

У звичайних об'єктів немає prototype, а у функцій-конструкторів є обидва: і prototype, і __proto__.


У сучасних реаліях

Властивість __proto__ вважається застарілою (legacy). Рекомендується використовувати сучасні аналоги:

javascript
Object.getPrototypeOf(obj); // замість obj.__proto__ Object.setPrototypeOf(obj, proto); // замість obj.__proto__ = proto

Підсумкова таблиця

ВластивістьДе використовуєтьсяЩо зберігаєКоли застосовується
__proto__у об'єктапосилання на його реальний прототипколи потрібно дізнатися "хто мій батько"
prototypeу функції-конструктора або класуоб'єкт, який стане прототипом створюваних об'єктівколи створюєш методи, доступні всім екземплярам

Ключовий зв'язок

javascript
instance.__proto__ === Constructor.prototype

Кожен об'єкт, створений через new Constructor(), отримує посилання на Constructor.prototype у своїй внутрішній властивості __proto__.


В одній фразі:

prototype - це "план" або "шаблон", звідки беруться методи для нових об'єктів. __proto__ - це "вказівник" об'єкта на той шаблон, звідки він усе успадковує.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.