Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Способи створення об'єкта». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Об'єкт у JavaScript створюють літералом `{}`, через `new Object()`, функцією-конструктором з `new`, класом `class`, фабричною функцією, через `Object.create(proto)`, а також з готових даних: `JSON.parse()`, `Object.assign()`, spread `{ ...obj }` і `Object.fromEntries()`.** Літерал покриває більшість випадків, `class` і функція-конструктор потрібні для шаблонних об'єктів, `Object.create()` задає прототип явно, а spread і `Object.assign()` копіюють та зливають наявні об'єкти. ```javascript const user = { name: 'Oleh', age: 25 }; // літерал const copy = { ...user, city: 'Kyiv' }; // spread const child = Object.create(user); // із заданим прототипом const parsed = JSON.parse('{"name":"Oleh"}'); // з рядка JSON ``` **Ключове:** у 90 відсотках випадків це літерал `{}`, решта способів потрібні для прототипів, шаблонів або копіювання.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**У JavaScript об'єкт можна створити щонайменше десятьма способами, від літерала `{}` до `Object.fromEntries()`.** Вибір залежить від того, чи потрібен шаблон із методами, чи явний прототип, чи просто копія наявних даних. ## Теорія ### TL;DR - Об'єктний літерал `{}` це найчитабельніший і найчастіший спосіб. - `new Object()` робить те саме, але виглядає застаріло і майже не використовується. - Функція-конструктор із `new` і `class` створюють об'єкти «за шаблоном», `class` це синтаксичний цукор над функцією. - Фабрична функція просто повертає об'єкт, без `new` і без прототипного спадкування. - `Object.create(proto)` задає прототип явно. - `JSON.parse()`, `Object.assign()`, spread `{ ...obj }` і `Object.fromEntries()` створюють об'єкт із готових даних. ### Швидкий приклад ```javascript const user = { name: 'Oleh', age: 25, isAdmin: false }; // властивості можна додавати і видаляти динамічно user.city = 'Kyiv'; delete user.isAdmin; console.log(user); // { name: 'Oleh', age: 25, city: 'Kyiv' } ``` ### Літерал і new Object() Об'єктний літерал це найпростіший і найпоширеніший спосіб: ```javascript const user = { name: 'Oleh', age: 25, isAdmin: false }; ``` Той самий результат через конструктор: ```javascript const user = new Object(); user.name = 'Oleh'; user.age = 25; ``` `new Object()` робить рівно те саме, що `{}`, але довше і виглядає «по-старому», тому зараз майже не використовується. ### Шаблони: функція-конструктор і class До появи `class` об'єкти «за шаблоном» створювали саме функцією-конструктором: ```javascript function User(name, age) { this.name = name; this.age = age; } const oleh = new User('Oleh', 25); const alice = new User('Alice', 30); console.log(oleh.name); // "Oleh" ``` Коли функцію викликають із `new`, рушій під капотом: 1. створює порожній об'єкт `{}`; 2. присвоює його `this`; 3. повертає цей об'єкт (якщо функція явно не повернула інший). `class` з ES6 це той самий механізм, але зручніший синтаксис: ```javascript class User { constructor(name, age) { this.name = name; this.age = age; } sayHi() { console.log(`Привіт, я ${this.name}`); } } const oleh = new User('Oleh', 25); oleh.sayHi(); // "Привіт, я Oleh" ``` Методи класу живуть у `User.prototype`, тобто одна копія методу на всі екземпляри. ### Фабрична функція і Object.create() Замість `class` чи `new` можна просто повернути об'єкт: ```javascript function createUser(name, age) { return { name, age, sayHi() { console.log(`Привіт, ${this.name}`); } }; } const oleh = createUser('Oleh', 25); oleh.sayHi(); // "Привіт, Oleh" ``` Дуже зручний спосіб, особливо коли не потрібні `prototype` і спадкування. Мінус у тому, що кожен екземпляр отримує власну копію методу. `Object.create()` створює новий об'єкт із вказаним прототипом: ```javascript const person = { greet() { console.log(`Привіт, я ${this.name}`); } }; const user = Object.create(person); user.name = 'Oleh'; user.greet(); // "Привіт, я Oleh" ``` Використовується, коли треба явно задати ланцюжок прототипів (prototype chain). Окремий випадок, `Object.create(null)`, дає «чистий» об'єкт без жодних успадкованих методів, зручний як словник. ### Створення з готових даних З рядка JSON, типовий випадок для відповіді сервера: ```javascript const json = '{"name": "Oleh", "age": 25}'; const user = JSON.parse(json); console.log(user.name); // "Oleh" ``` Працює тільки з простими типами даних, методи через JSON не передаються. `Object.assign()` створює об'єкт на основі інших, копіюючи властивості: ```javascript const base = { a: 1 }; const extra = { b: 2 }; const result = Object.assign({}, base, extra); console.log(result); // { a: 1, b: 2 } ``` Spread-синтаксис робить те саме коротше і є сучасним стандартом копіювання та об'єднання: ```javascript const user = { name: 'Oleh', age: 25 }; const copy = { ...user, city: 'Kyiv' }; console.log(copy); // { name: 'Oleh', age: 25, city: 'Kyiv' } ``` `Object.fromEntries()` збирає об'єкт із масиву пар `[ключ, значення]`: ```javascript const entries = [['name', 'Oleh'], ['age', 25]]; const user = Object.fromEntries(entries); console.log(user); // { name: 'Oleh', age: 25 } ``` ### Що обирати | Спосіб | Приклад | Особливості | | --- | --- | --- | | Об'єктний літерал | `{ name: 'Oleh' }` | найчастіший спосіб | | `new Object()` | `new Object()` | рідко використовується | | Функція-конструктор | `function User() { this.name = ... }` | стара альтернатива `class` | | `class` | `class User { ... }` | сучасний ООП-підхід | | Фабрична функція | `function createUser() { return {...} }` | без `this`, просто повертає об'єкт | | `Object.create(proto)` | `Object.create(person)` | створює об'єкт із заданим прототипом | | `JSON.parse()` | `JSON.parse('{"a":1}')` | створює об'єкт із рядка | | `Object.assign()` | `Object.assign({}, obj1, obj2)` | копіює та зливає об'єкти | | Spread-синтаксис | `{ ...obj1, ...obj2 }` | короткий синтаксис копіювання | | `Object.fromEntries()` | `Object.fromEntries([['a', 1]])` | з масиву пар в об'єкт | Коротко: найпопулярніший спосіб це `{}`, для спадкування `Object.create()`, для шаблонів `class` або функція-конструктор, для копіювання `{ ...obj }` чи `Object.assign()`. ### Типові помилки - **Виклик функції-конструктора без `new`.** У звичайному режимі `this` вкаже на глобальний об'єкт і засмітить його, у strict mode буде `TypeError`. - **Очікувати глибоку копію від spread чи `Object.assign()`.** Обидва копіюють поверхнево: вкладені об'єкти лишаються спільними. Для глибокої копії беріть `structuredClone()`. - **Використовувати `JSON.parse(JSON.stringify(obj))` як універсальний клон.** Втрачаються функції, `undefined`, `Date` перетворюється на рядок, а циклічні посилання кидають помилку. - **Плутати `Object.create(proto)` і `new`.** Перше просто ставить прототип, друге ще й виконує конструктор. - **Створювати методи у фабричній функції для тисяч об'єктів.** Кожен екземпляр отримує власну копію функції, тоді як `class` тримає одну в прототипі. - **Використовувати звичайний `{}` як словник для довільних ключів.** Ключі на кшталт `__proto__` або `toString` конфліктують із прототипом, безпечніші `Object.create(null)` або `Map`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.