Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Перевірка на екземпляр класу». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Основний спосіб перевірити, що об'єкт є екземпляром класу, це оператор `obj instanceof Class`: він перевіряє, чи є посилання на `Class.prototype` у **ланцюжку прототипів** об'єкта, і повертає `true` навіть для нащадків завдяки успадкуванню. **Ключове:** альтернативи на кшталт `obj.constructor === Class` чи `Object.getPrototypeOf(obj) === Class.prototype` менш надійні (перша ламається при зміненому `prototype`, друга не піднімається по ланцюжку успадкування), а для перевірки масивів між різними контекстами (iframe, Worker) варто використовувати `Array.isArray()` замість `instanceof`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Оператор `instanceof`: основний спосіб ```javascript class User {} const u = new User(); console.log(u instanceof User); // true ``` `instanceof` перевіряє, чи є в **ланцюжку прототипів** об'єкта `u` посилання на `User.prototype`. --- ### Приклад: ```javascript class Animal {} class Dog extends Animal {} const dog = new Dog(); console.log(dog instanceof Dog); // true console.log(dog instanceof Animal); // true: успадкування працює console.log(dog instanceof Object); // true: усі об'єкти успадковують від Object ``` `instanceof` йде **по ланцюжку прототипів угору**, і якщо знаходить збіг із `Class.prototype`, повертає `true`. --- ## 2. Як `instanceof` працює під капотом ```javascript obj instanceof Class ``` приблизно еквівалентно такому коду: ```javascript let proto = Object.getPrototypeOf(obj); while (proto) { if (proto === Class.prototype) return true; proto = Object.getPrototypeOf(proto); } return false; ``` Тобто `instanceof` просто **перевіряє наявність** `Class.prototype` **у ланцюжку** `__proto__`. --- ## 3. Приклад, де успадкування впливає на результат ```javascript class A {} class B extends A {} class C extends B {} const c = new C(); console.log(c instanceof A); // true console.log(c instanceof B); // true console.log(c instanceof C); // true ``` Ланцюжок прототипів: ```javascript c → C.prototype → B.prototype → A.prototype → Object.prototype → null ``` `instanceof` послідовно йде вгору по ланцюжку. --- ## 4. Перевірка без `instanceof`: через `constructor` Можна перевірити, чи збігається конструктор об'єкта з класом: ```javascript class User {} const u = new User(); console.log(u.constructor === User); // true ``` Але: - Цей спосіб ламається, якщо об'єкт створено через `Object.create()`. - Або якщо хтось змінив `prototype.constructor`. ```javascript const fake = Object.create(User.prototype); console.log(fake.constructor === User); // true console.log(fake instanceof User); // true ``` > Обидва способи працюють, доки ланцюжок прототипів не зламано. --- ## 5. Альтернатива: через `Object.getPrototypeOf` ```javascript class User {} const u = new User(); console.log(Object.getPrototypeOf(u) === User.prototype); // true ``` Працює **лише для прямого екземпляра**. Якщо є успадкування, цей метод не піднімається вище по ланцюжку (на відміну від `instanceof`). --- ## 6. Перевірка вбудованих класів (Array, Date, Error, Map та ін.) ```javascript console.log([] instanceof Array); // true console.log([] instanceof Object); // true console.log(new Date() instanceof Date); // true console.log(new Date() instanceof Object); // true ``` `instanceof` працює зі **вбудованими класами** точно так само, адже вони теж побудовані на прототипах. --- ## 7. Важливо при роботі з різними "реальностями" (iframe, worker тощо) Якщо об'єкт створено в **іншому контексті (наприклад, іншому iframe)**, його `Array` чи `Object`, це **інший конструктор**, тому `instanceof` може повернути `false`. ```javascript // В іншому iframe: console.log(arr instanceof window.Array); // false ``` Рішення: використовувати ```javascript Array.isArray(arr); // безпечно навіть між контекстами ``` --- ## 8. Приклад зі статичним методом перевірки Іноді до класу додають **власний метод перевірки**: ```javascript class User { static isUser(obj) { return obj instanceof User; } } const u = new User(); console.log(User.isUser(u)); // true ``` Такий метод корисний у великих кодових базах, де типи часто перевіряються централізовано. --- ## Підсумок | Спосіб | Приклад | Перевіряє | Підтримує успадкування | Примітка | | --- | --- | --- | --- | --- | | `instanceof` | `obj instanceof Class` | Ланцюжок `__proto__` | Так | Надійний | | `constructor` | `obj.constructor === Class` | Конструктор об'єкта | Частково | Ламається при зміненому `prototype` | | `Object.getPrototypeOf` | `Object.getPrototypeOf(obj) === Class.prototype` | Прямий прототип | Ні | Лише для прямого класу | | Статичний метод | `Class.isInstance(obj)` | Будь-яка логіка | Так | Зручно у великих проєктах | --- **Коротко:** > Перевірити, що об'єкт є екземпляром класу, можна так: > > ```javascript > obj instanceof Class > ``` > > Цей оператор: > > - йде по ланцюжку прототипів (`__proto__`); > - підтримує успадкування; > - працює і зі вбудованими класами (`Array`, `Date`, `Error`); > - але може бути ненадійним між контекстами (iframe, Worker).Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.