Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чим стрілкові методи відрізняються від звичайних?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Стрілковий метод** (метод-поле) - це метод класу, оголошений через `= () => {}`; на відміну від звичайного методу, його `this` **жорстко прив'язується** до екземпляра ще під час створення об'єкта, а не визначається в момент виклику. **Ключове:** звичайний метод зберігається один раз у `Class.prototype` і підтримує `super`, а стрілковий створюється заново для кожного екземпляра, не бере участі в успадкуванні, зате ніколи не втрачає `this` при передаванні як колбек.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Синтаксис **Звичайний метод:** ```javascript class Button { handleClick() { console.log(this.label); } } ``` **Стрілковий метод (метод-поле):** ```javascript class Button { handleClick = () => { console.log(this.label); }; } ``` На перший погляд, відмінність лише в `= () => {}`. Але поведінка **радикально інша**. --- ## 2. Головна відмінність: поведінка `this` | Тип методу | Як працює `this` | | --- | --- | | **Звичайний метод** | `this` визначається **в момент виклику** (динамічно) | | **Стрілковий метод** | `this` **жорстко прив'язаний** до екземпляра під час створення об'єкта | ### Приклад: ```javascript class User { name = "Alice"; normal() { console.log("normal:", this.name); } arrow = () => { console.log("arrow:", this.name); }; } const u = new User(); setTimeout(u.normal, 500); // TypeError: Cannot read properties of undefined setTimeout(u.arrow, 500); // arrow: Alice ``` **Висновок:** - `normal()` втратив контекст, бо викликаний як звичайна функція. - `arrow()` зберіг контекст, бо стрілкова функція не має власного `this`, вона "захоплює" `this` із конструктора. --- ## 3. Де зберігаються методи | Тип методу | Де зберігається | Спільний для всіх екземплярів? | | --- | --- | --- | | **Звичайний** | У `ClassName.prototype` | Так | | **Стрілковий** | У самому екземплярі (на кожному об'єкті) | Ні | ### Приклад: ```javascript class A { normal() {} arrow = () => {}; } const a1 = new A(); const a2 = new A(); console.log(a1.normal === a2.normal); // true: один метод у прототипі console.log(a1.arrow === a2.arrow); // false: у кожного своя функція ``` **Висновок:** Стрілкові методи **створюються заново** під час кожного `new A()`. Це дає незалежність `this`, але трохи **гірше за пам'яттю та продуктивністю**. --- ## 4. Використання в обробниках подій і колбеках Звичайний метод втрачає `this`, якщо не прив'язати вручну: ```javascript class Button { constructor() { this.label = "Click me"; document.body.addEventListener("click", this.handleClick); } handleClick() { console.log(this.label); // undefined } } ``` Рішення 1: прив'язати вручну ```javascript document.body.addEventListener("click", this.handleClick.bind(this)); ``` Рішення 2 (сучасніше): використати стрілковий метод ```javascript class Button { label = "Click me"; handleClick = () => { console.log(this.label); // "Click me" }; } ``` Стрілкові методи ідеально підходять для **React-компонентів** і **обробників подій**, де важливо, щоб `this` не втрачався. --- ## 5. Успадкування і перевизначення - **Звичайні методи** можна легко перевизначати в нащадках (через `super`). - **Стрілкові методи** не можна перевизначити через `super`, бо вони створюються **в екземплярі**, а не в прототипі. ```javascript class A { greet() { console.log("Hi from A"); } } class B extends A { greet() { super.greet(); // працює console.log("Hi from B"); } } ``` А зі стрілковим: ```javascript class A { greet = () => console.log("Hi from A"); } class B extends A { greet = () => { super.greet(); // Помилка: super недоступний }; } ``` Тому стрілкові методи **не підходять для класів, що успадковуються**, якщо потрібно використовувати `super`. --- ## 6. Відмінність під час ітерації та відлагодження - **Звичайні методи** не видно при `Object.keys()` (вони неперелічувані). - **Стрілкові методи**, це звичайні властивості екземпляра, тому вони **перелічувані**: ```javascript class Example { method() {} arrow = () => {}; } const e = new Example(); console.log(Object.keys(e)); // ['arrow'] ``` --- ## 7. Продуктивність | Критерій | Звичайний метод | Стрілковий метод | | --- | --- | --- | | Пам'ять | 1 функція на всіх | своя функція в кожного | | Швидкість створення | Швидше | Повільніше | | Контекст `this` | Втрачається, якщо не bind | Завжди зберігається | | Підходить для `super` | Так | Ні | | Підходить для колбеків | Потрібен bind | Ідеальний | --- ## Підсумкове порівняння | Особливість | Звичайний метод | Стрілковий метод | | --- | --- | --- | | Де зберігається | `Class.prototype` | В екземплярі | | Спільний для всіх | Так | Ні | | Поведінка `this` | Залежить від виклику | Фіксована | | Втрата `this` у колбеках | Можлива | Немає | | Підтримка `super` | Так | Ні | | Бере участь в успадкуванні | Так | Ні | | Продуктивність | Краще | Трохи гірше | | Використання в React, подіях | Незручно | Дуже зручно | --- **Висновок:** - Використовуй **звичайні методи**, якщо метод логічно спільний для всіх екземплярів і може бути перевизначений. - Використовуй **стрілкові методи**, якщо важливо зберегти `this` (наприклад, під час передавання методу як колбека або обробника події).Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.