Прототип
Я вирішив поговорити про це, оскільки вважаю, що це одна з найбільш заплутаних тем в JS. У середньому, під час кожного інтерв'ю, принаймні одне запитання обов'язково стосується цієї теми.
Прототип
Примітка: "Прототип" - це спеціальне властивість, доступна лише для об'єктів-функцій.
Ця властивість автоматично надається функціям при їх запуску.
Майже кожен об'єкт пов'язаний з іншим об'єктом. Ця зв'язок встановлюється за допомогою прототипу. Об'єкти успадковують методи та властивості батьківського об'єкта через прототип.
Властивість prototype
є в самій функції (Animal
), а не в її екземплярах (Dog
).
Щоб краще зрозуміти, давайте спробуємо розібрати наступний приклад крок за кроком:
Спершу подивимося, що відбувається при виконанні першого рядка:
Коли функція виконується, до Animal
(ознаки того, що вона оголошена з ключовим словом function) автоматично додається властивість.
Що стається, коли створюється об'єкт Dog?
- Тригерується
Animal.prototype.constructor
і створюється новий об'єкт. - Новий об'єкт призначається змінній Dog. (
Dog = {}
) - Створюється властивість
Dog
, яка вказує на__proto__
батьківського прототипу. (Dog.__proto__ === Animal.prototype
)
Додатково, давайте додамо до Animal
властивість color
Оскільки у Dog
немає властивості кольору, то властивість Dog.__proto__
буде шукати її та поверне після знаходження.
Прототип: __proto__ проти [[Prototype]]
Що таке
[[Prototype]]
? (Приватне)
Це приватний об'єкт, який використовується JavaScript на задньому плані ( недоступний розробнику ), що показує прототип об'єкту.
Що таке
__proto__
? (Публічне)
Це внутрішній властивість, яка обов'язково присутня в кожному об'єкті.
[[Prototype]]
Оскільки ми не можемо звертатися до нього напряму, для цього ми користуємося властивістю
__proto__
може бути або Object, або Null.
Як ми можемо створити об'єкт без прототипу?
Загалом, кожен об'єкт в JS успадковує Object, а Object.prototype завжди є Null.
Object.create(null)
ПРИМІТКА: Пряме встановлення __proto__ вже не рекомендується JavaScript. (Doberman.__proto__ = Dog)
УСТАРІЛЕ. Це наведено лише для прикладу. НЕ РОБІТЬ ТАК у реальному коді. //джерело: Mozilla
Pрототипна Ланцюг
Усі об'єкти в JS є екземплярами Object .
Кожен об'єкт може успадковувати лише один об'єкт одночасно.
Об'єкти
Як шукати будь-яке поле об'єкта?
- Спочатку поле
object
шукається у ньому самому, якщо знайдено, воно повертається,
якщо не знайдено, шукається також object.__proto__
.
Якщо його ще не знайдено, воно шукається в object.__proto__.__proto__
Процес продовжується в такому порядку (object.__proto__.__proto__.__proto__
) до досягнення Глобального Об'єкту
- Якщо в кінці не можна знайти результат, повертається
undefined
.
У прикладі нижче, успадковані поля (code, name
) не знаходяться всередині District
, тому вони повертаються зсередини District.__proto__
.
markdown
ПЕРЕКЛАД ТЕКСТУ НА УКРАЇНСЬКУ
Масиви та функції
Давайте розглянемо, що успадковується при створенні масиву:
- Перший успадковує властивості від
Array.prototype
, тому має методи, такі якforEach
,join
. - Потім успадковує властивості від
Object.prototype
, тому об'єкт має методи, такі якtoString
,keys
.
Щодо функцій:
- Перша успадковує властивості від
Function.prototype
, тому має методи, такі якcall
,bind
. - Потім успадковує властивості від
Object.prototype
, тому об'єкт має методи, такі якtoString
,keys
.
З допомогою Object.create()
Метод Object.create()
дозволяє створити новий об'єкт з використанням існуючого, створюючи ланцюг прототипів.
Значення null
означає відсутність прототипу.
У випадку видалення b.id
з b
, id
залишається в a
, оскільки id
є в b.__proto__
.
Якщо було б видалено a.id
, це призвело б до видалення з обох.
Методи-доступу та задавачі
Як бачимо з прикладу, методи setColor
та getColor
належать об'єкту Dog
. Оскільки ми успадкували Doberman
від Dog
, ці методи вже існують в Dog
.
Зверніть увагу, що методи setColor
та getColor
змінюють лише властивість об'єкта, з якими вони взаємодіють.
Ітерація
Для перебору властивостей успадкованого об'єкта також використовується цикл For in.
Для кожного класу наслідника, такого як Dog та Cat, також буде доступна властивість color, оскільки всі об'єкти успадковують тип Object.
Глобальний об'єкт як функція
Глобальний об’єкт може бути викликаний як функція, що означає, що глобальний об’єкт фактично є функцією. Тому він має властивість prototype.
Усі об'єкти успадковують тип Object, у тому числі Dog та Cat.
Це означає, що Dog.__proto__ та Cat.__proto__ також мають властивість color.
Оператор "instanceof"
Припустимо, у нас є об'єкт dog і ми хочемо перевірити, чи належить він класу Dog.
Ми можемо використовувати оператор instanceof наступним чином:
Завершивши розгляд методів, можна подивитися на процес з діаграмою:
Для більш чіткого уявлення, можна переглянути діаграму за посиланням:
Завдання
Переклад тексту з використанням markdown розмітки:
`drawio#R7Vz%2Fc6I4FP9r%2FPE6BAT1x9Ntd2dub6%2FX3s7e%2FdRJJZXsIGFDrLV%2F%2FQVIRAwItIrU4DgjeYYA7%2FPy3vvkCwNrtnz5TGHo%2FUlc5A9Mw30ZWJ8GpgnAxOE%2FsWSTSqyRnQoWFLuiUia4x69ICA0hXWEXRbmKjBCf4TAvnJMgQHOWk0FKyTpf7Yn4%2BauGcIEUwf0c%2Bqr0B3aZl0rHtpHJvyC88OSVgSH%2BWUJZWQgiD7pkvSOyrgfWjBLC0qPlywz5sfKkXtLzbkr%2B3d4YRQGrc8L3z3%2F%2FWtwtnxfkB549rn%2B%2Fnf6Bf5ukrTxDfyUeOEQ0IoFoPWIbqYhojZc%2BDHhp%2BoR9f0Z8QpN%2FLMe5uXEcLhdtIcrQS%2BlNgu2jc5tBZIkY3fAq4gRnKLQlzMURxXWme1Nq...
Переклад:
Текст
![image](https://miro.
Посилання на діаграму:
[Посилання на діаграму:](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1&title=Untitled+Diagram.
На чому зображені дві діаграми зображуючі структуру даних мережі, і синтаксичну модель, співвідношення між даними та сервером (Server-Data Relationship), і інші концепції. Обидві діаграми можна переглянути за посиланням вище.
Я сподіваюся, що це було корисно...
Переклади текст вище на українську з збереженням markdown розмітки.
Адаптуй речення, щоб українська стала природньою.
У markdown всі вставки коду робляться через замість звичайних для маркдаун потрійних лапок.
Після кожного англійського терміна по програмуванню, наприклад, "прослуховувач подій" додавай цей термін англійською в дужках (Event Listener).
У перекладі не використовуй заголовок ## більше одного разу - краще заміни його на #.
Перекладено з: proto, prototype, [[Prototype]], Prototype Chain