Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Геттери та сеттери в об'єкті». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Геттер, це функція, яка викликається під час читання властивості, а сеттер, функція, яка викликається під час присвоєння значення.** В об'єктному літералі їх оголошують ключовими словами `get` і `set` перед іменем властивості, а для наявного об'єкта, через `Object.defineProperty()`. Ззовні така властивість виглядає як звичайна, але за нею стоять функції, тому геттери та сеттери використовують для обчислюваних значень, валідації та інкапсуляції. ```javascript const user = { firstName: 'Maria', lastName: 'Kovalenko', get fullName() { return `${this.firstName} ${this.lastName}`; } }; console.log(user.fullName); // "Maria Kovalenko" ``` **Ключове:** `obj.prop` викликає `get prop()`, а `obj.prop = value` викликає `set prop(value)`, дужок писати не треба.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Геттер і сеттер, це функції-аксесори, які прив'язані до імені властивості: геттер спрацьовує на читанні, сеттер, на присвоєнні.** Їх оголошують просто в об'єктному літералі через `get` і `set` або додають до наявного об'єкта через `Object.defineProperty()`. ## Теорія ### TL;DR - **Геттер (getter)**, функція, яка викликається під час **читання** властивості. - **Сеттер (setter)**, функція, яка викликається під час **присвоєння** значення. - Синтаксис у літералі: `get prop() { ... }` і `set prop(value) { ... }`. - Ззовні властивість виглядає звичайною: `obj.prop` і `obj.prop = 5`, без дужок виклику. - Головні сценарії: обчислювані властивості, валідація вхідних даних, інкапсуляція внутрішнього поля. - `Object.defineProperty()` дає те саме, але дозволяє ще й налаштувати `enumerable`, `configurable` тощо. ### Швидкий приклад ```javascript const user = { firstName: 'Maria', lastName: 'Kovalenko', get fullName() { return `${this.firstName} ${this.lastName}`; } }; console.log(user.fullName); // "Maria Kovalenko", викликався геттер ``` ### Що таке геттер і сеттер - **Геттер (getter)**, це функція, яка **викликається при читанні** властивості. - **Сеттер (setter)**, це функція, яка **викликається при присвоєнні** значення. Вони дозволяють зробити властивості обчислюваними або контролювати, що саме записується в об'єкт. Значення геттер не зберігає: він рахує його щоразу заново з інших полів. ### Синтаксис усередині об'єктного літерала ```javascript const user = { firstName: 'Maria', lastName: 'Kovalenko', // геттер get fullName() { return `${this.firstName} ${this.lastName}`; }, // сеттер set fullName(value) { const [first, last] = value.split(' '); this.firstName = first; this.lastName = last; } }; console.log(user.fullName); // "Maria Kovalenko", викликався getter user.fullName = 'Oleh Petrenko'; // викликався setter console.log(user.firstName); // "Oleh" console.log(user.lastName); // "Petrenko" ``` Як це працює: | Операція | Що відбувається | | --- | --- | | `user.fullName` | викликає **геттер**, повертає значення | | `user.fullName = '...'` | викликає **сеттер**, обробляє присвоєння | Тобто `fullName` виглядає як звичайна властивість, але за нею приховані функції. Сеттер завжди приймає рівно один параметр, значення, яке присвоюють. ### Приклад з перевіркою значення (валідацією) ```javascript const product = { _price: 0, // внутрішнє сховище get price() { return this._price; }, set price(value) { if (value < 0) { console.error('Price cannot be negative'); return; } this._price = value; } }; product.price = 500; // setter спрацював console.log(product.price); // 500, getter спрацював product.price = -10; // відхилено, значення не змінилося ``` Зазвичай геттери та сеттери працюють із «внутрішніми» полями, імена яких починаються з `_`. Це домовленість, а не захист мови: доступ до `product._price` залишається відкритим. Якщо потрібна справжня приватність, використовуйте приватні поля класів `#price`. ### Через Object.defineProperty(), альтернативний спосіб ```javascript const user = { firstName: 'Maria', lastName: 'Kovalenko' }; Object.defineProperty(user, 'fullName', { get() { return `${this.firstName} ${this.lastName}`; }, set(value) { const [first, last] = value.split(' '); this.firstName = first; this.lastName = last; } }); console.log(user.fullName); // "Maria Kovalenko" user.fullName = 'Oleh Petrenko'; console.log(user.firstName); // "Oleh" ``` Цей спосіб гнучкіший: можна налаштувати додаткові атрибути (`enumerable`, `configurable` тощо). Зверніть увагу, що за замовчуванням `Object.defineProperty()` робить властивість неперелічуваною, тоді як у літералі аксесор перелічуваний. ### Підсумкова таблиця | Елемент | Що робить | Синтаксис | | --- | --- | --- | | **getter** | повертає значення під час читання | `get prop() { ... }` | | **setter** | викликається під час присвоєння | `set prop(value) { ... }` | | **читання** | викликає `get` | `obj.prop` | | **запис** | викликає `set` | `obj.prop = ...` | | **де застосовують** | інкапсуляція, валідація, обчислювані значення | Так | ### Типові помилки - **Викликати аксесор як метод.** `user.fullName()` спричинить помилку: геттер уже повернув рядок, а рядок не є функцією. - **Іменувати внутрішнє поле так само, як аксесор.** `get price() { return this.price; }` дає нескінченну рекурсію і `RangeError`. Внутрішнє поле має називатися інакше, наприклад `_price`. - **Оголошувати тільки геттер і дивуватися «мовчазному» присвоєнню.** Без сеттера запис у нестрогому режимі просто ігнорується, а в `'use strict'` кидає `TypeError`. - **Робити геттер важким.** Він виглядає як звичайне читання поля, тому виклик у циклі непомітно перетворюється на сотні обчислень. Важкі операції краще залишати звичайним методом. - **Плутати `_price` з приватністю.** Підкреслення це лише угода про іменування; справжню приватність дають приватні поля класів `#price` або замикання. - **Забувати, що `JSON.stringify()` бачить геттер.** Він серіалізує результат геттера як звичайне поле, тому у вихідний JSON може потрапити обчислюване значення.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.