Опанування стрілки та її функцій у JavaScript

Останнє оновлення: 28/01/2026
Автор: Ісаак
  • Стрілкові функції спрощують синтаксис та лексично фіксують значення `this`, на відміну від звичайних функцій.
  • JavaScript визначає `this` у класичних функціях за чотирма правилами: явне зв'язування, неявне зв'язування, зв'язування з `new` та зв'язування за замовчуванням.
  • Стрілкові функції ідеально підходять для зворотних викликів та асинхронного коду, але їх не слід використовувати як методи, що залежать від `this`, або як конструктори.
  • Оволодіння комбінованим використанням звичайних функцій, стрілкових функцій та таких методів, як call, apply та bind, є ключем до написання сучасного та надійного JavaScript.

Різниця між "hello world" у Python, JavaScript, Java, C, C++, Go, Swift, R, Ruby, Rust, VBA, C#, COBOL та Fortran

Ретельно опануйте стрілкові функції та поведінка `this` у JavaScript Це знаменує собою поворотний момент у ваших навичках розробки. Спочатку ці дві теми здаються заплутаними, але як тільки ви їх зрозумієте, ви почнете помічати помилки, які раніше вам не приділяли уваги, ви напишете чіткіший код і менше матимете труднощів з контекстом.

У цій статті ми спокійно та прямо розглянемо, Як пишуться стрілкові функції, які відмінності між ними та звичайними функціями, і як все це впливає на `this`?Крім того, ми інтегруємо ключові концепції, такі як call, apply, bind, використання new, різні типи цього зв'язування, як воно поводиться в класах, подіях, зворотних викликах, середовищах, таких як React або Node.js, та в яких випадках має сенс використовувати або уникати стрілкових функцій.

Базовий синтаксис стрілкових функцій

Стрілочна функція записується з використанням символу => і це завжди функціональний виразТобто, вона не оголошується з функцією name(), а присвоюється змінній або властивості.

Загальний формат приблизно такий: const myFunction = (param1, param2) => { /* код */ }Так само, як класична анонімна функція, але слово function замінюється на стрілку =>, а дужки використовуються для параметрів, а фігурні фігури — для тіла функції.

Важливо це розуміти Стрілочні функції не є оголошеннями функційВи не можете використовувати їх перед визначенням, оскільки вони не піднімаються (підняття не відбувається так само, як і у випадку з `function name()`). Вони завжди поводяться як вирази, що обчислюються, коли інтерпретатор проходить через цей рядок.

Синтаксичні скорочення: коротші версії стрілкових функцій

Коли код всередині функції дуже простий, стрілкові функції дозволяють більш компактний та читабельний синтаксисЯкщо тіло має лише один оператор, і цей оператор є поверненням значення, можна пропустити кілька речей:

  • Слово можна видалити функція (Насправді, ми його вже видалили).
  • Їх можна видалити ключі {}.
  • Слово можна пропустити повертати, використовуючи неявне повернення.

Наприклад, замість того, щоб писати суму типу const add = function(a, b) { повернути a + b; }, зі стрілкою ви можете залишити це в const додавання = (a, b) => a + b;Результат той самий, але код коротший і легший для читання, особливо у зворотних викликах та методах масивів.

Параметри у стрілкових функціях

Правила для параметрів дещо змінюються залежно від синтаксису, і важливо їх розуміти, оскільки на початку поширені дурні помилки:

  • Один параметрВи можете прибрати дужки та написати щось на кшталт ім'я => `Привіт, ${name}`Це цілком справедливо і дуже поширено.
  • Нульові параметри: дужки тут обов'язкові, оскільки вам потрібно щось перед стрілкою: () => console.log('Без параметрів').
  • Два або більше параметрівТакож потрібні дужки, наприклад (a, b, c) => a * b * c.

У всіх випадках, якщо тіло функції зводиться до простого виразу, ви можете Скористайтеся перевагами неявного повернення та відмовтеся від фігурних дужок та операторів повернення.що дуже практично в таких методах, як map, filter, reduce або в малих функціях перетворення.

Неявне повернення та повернення об'єкта

Коли стрілочна функція має лише один вираз, Значення цього виразу повертається автоматично Якщо ви не використовуєте фігурні дужки. Але коли ви хочете повернути літеральний об'єкт, є важливий трюк: вам потрібно обернути об'єкт у дужки.

Якщо ви напишете щось на кшталт const createUser = (ім'я, вік) => { ім'я: ім'я, вік: вік }JavaScript інтерпретує фігурні дужки як тіло функції, а не як об'єкт, що повертається, тому він нічого не повертає (undefined). Щоб це працювало, потрібно написати const createUser = (ім'я, вік) => ({ ім'я, вік }).

Коротше кажучи, щоразу, коли вашій стрілковій функції потрібно повернути об'єкт в одному рядку, оберніть цей об'єкт у дужки, щоб механізм зрозумів, що це повернене значення, а не блок коду.

Ключові відмінності між звичайними функціями та стрілковими функціями

Окрім синтаксису, для повсякденного життя справді важливо те, що Стрілкові функції поводяться інакше, ніж "звичайні" функції, у кількох критичних аспектах.: це, аргументи, використання як методів, конструкторів тощо.

Обробка цього у звичайних функціях

У класичній функції значення Це залежить від того, як викликається функціяне з того, де це визначено. Цей нюанс є джерелом значної частини плутанини.

  • Якщо ви викликаєте функцію типу об'єкт.method()У цьому методі this вказує на obj (неявне зв'язування).
  • Якщо викликати одну функцію, мояФункція(), без об'єкта попереду, у несуворому режимі це буде глобальний об'єкт (вікно у браузері), а у суворому режимі він буде невизначеним.
  • Якщо ви використовуєте нова МояФункція(), тоді в межах MyFunction це буде створений новий об'єкт (зв'язування з new).
  • Якщо ви використовуєте зателефонувати, подати заявку або зв'язатисяВи можете явно передати йому, який об'єкт ви хочете бачити.

Цей динамічний характер робить його дуже потужним, але також дуже легко розбити на зворотні виклики та асинхронний код якщо вам незрозуміло, звідки викликається кожна функція.

  Дізнайтеся, як відновити видалені нотатки на iPhone

Лексична обробка "this" у стрілкових функціях

Стрілкові функції повністю змінюють правила: У них цього немає власногоЗамість того, щоб отримувати нове «це» на основі своєї назви, вони фіксують «це» середовища, де вони були створені, що називається лексичним «це».

Це означає, що всередині стрілкової функції, Це саме те саме «це», що було в тому місці, де було визначено функцію.На це не впливає спосіб виклику чи виклики/застосування/прив'язки. Ця функція — чисте золото для роботи з методами масивів, setTimeout, setInterval, промісами та будь-якою ситуацією, де раніше доводилося поєднувати self = this або bind.

Чотири основні правила `this` в JavaScript

Щоб повністю зрозуміти, чому стрілкові функції такі корисні, важливо зрозуміти, як JavaScript визначає значення Це у звичайних функціяхІснує чотири основні правила, що застосовуються в такому порядку пріоритетності:

  1. Явне зв'язування: коли ви використовуєте call, apply або bind для виправлення цього.
  2. Неявне зв'язування: коли ви викликаєте метод як властивість об'єкта (obj.method()).
  3. Обв'язування з новим: коли ви викликаєте функцію з new, перетворюючи її на конструктор.
  4. Прив'язка за замовчуванням: коли жоден з перерахованих вище пунктів не застосовується (глобальний або невизначений залежно від режиму).

Функції стрілок обходять цю систему: Вони не беруть участі в цих правилах, бо ніколи не створюють своїх власних.Вони просто успадковують будь-який код, що знаходиться в навколишньому середовищі.

Явне зв'язування: виклик, застосування та зв'язування

Звичайні функції дозволяють примусово встановити значення цього, використовуючи три добре відомі методи: виклик, застосування та прив'язкаВони є фундаментальними для повного розуміння класичної моделі та порівняння її з поведінкою стрілкових функцій.

виклик та застосування: виконання з використанням власного `this`

Як виклик, так і звернення служать для негайно викликати функцію з конкретним `this`Різниця полягає в тому, як ви передаєте аргументи: call отримує їх по одному, apply отримує масив.

Наприклад, якщо у вас є функція, яка вітає за допомогою `this.name`, ви можете викликати цю функцію з різними об'єктами та повторно використовувати логіку. Це дуже поширене явище, коли ви хочете Спільне використання функцій між об'єктами без дублювання коду.

bind: створити нову функцію з `this`

bind працює по-іншому: замість виконання в даний момент, Він повертає нову функцію, в якій this "прив'язується" до об'єкта, якому ви його передаєте.Крім того, ви можете заздалегідь встановити аргументи (часткове застосування), щоб результуюча функція вже мала деякі попередньо визначені параметри.

Це дуже корисно, коли потрібно передавати методи як зворотні виклики без втрати їхнього початкового контекстуНаприклад, у слухачах подій або в setInterval, де це зазвичай переривається.

Важливою деталлю є це Функція, яка вже пов'язана з bind, ігнорує наступні спроби змінити `this` за допомогою `call` або `apply`Прив'язка є постійною для цієї похідної функції.

Неявне зв'язування та втрата контексту

Неявне зв'язування відбувається, коли Ви викликаєте функцію як метод об'єктаТобто, ліворуч від точки є щось. У такому випадку «це» стає тим самим об'єктом.

Наприклад, якщо у вас є об'єкт ресторану з методами welcomeGuest та cookPizza, коли ви це зробите ресторан.вітаємоГість()У методі `this` він вказує на сам ресторан, що дозволяє отримати доступ до таких властивостей, як назва або місцезнаходження.

Проблема починається, коли відокремити метод від об'єктаНаприклад, передаючи його як зворотний виклик: `setInterval(this.tick, 1000)`. Коли таймер виконується, ліворуч від позначення більше немає об'єкта. Неявне зв'язування втрачається, і бере на себе зв'язування за замовчуванням, роблячи `this` глобальним або невизначеним, і ваш код завершується невдачею.

Класичним рішенням було використання зв'язати(це) або зберігати посилання, наприклад, const self = this. У наш час, Функції зі стрілками ідеально підходять для вирішення проблеми втрати контекстуоскільки вони успадковують зовнішній `this` і не змінюють його, навіть якщо ви передаєте їх як зворотні виклики.

Конструктори, нові та ці

Коли ви викликаєте функцію з newJavaScript автоматично виконує кілька дій, щоб розглядати його як конструктор:

  • Створіть новий порожній об'єкт.
  • Прив’яжи Це новий об'єкт в межах функції.
  • Налаштуйте прототип нового об'єкта відповідно до прототипу конструктора.
  • Повернути об'єкт, якщо ви явно не повернете інший об'єкт.

Завдяки цьому, такий будівельник, як функція Особа(ім'я) { this.name = ім'я; } Це дозволяє виконати `const p = new Persona('Ana');` та мати об'єкт із властивістю `name`. Всередині конструктора `this` посилається на щойно створений екземпляр.

Цей шаблон також використовується для проектування складніших структур, таких як банківський рахунок з методами внесення та зняття коштів або транспортний засіб з методами керування та властивостями, такими як рік випуску та модель. У всіх цих випадках Це конкретний екземпляр, з яким ви працюєте..

Дуже важливо: Стрілкові функції не можна використовувати як конструкториВони не підтримують використання `new`, і якщо ви спробуєте, то отримаєте помилку. Оскільки в них немає власних `this` або `prototype`, вони не вписуються в цю модель.

Прив'язка за замовчуванням та суворий режим

Коли не застосовується ні явне зв'язування, ні неявне зв'язування, ні оператор new, JavaScript вдається до зв'язування за замовчуванням:

  • У несуворому режимі, Це вказує на глобальний об'єкт (вікно у браузері, глобальне у Node.js).
  • У суворому режимі («використовувати суворий»), Це не визначено у звичайній функції під назвою «без сідла».

Ця сувора зміна дуже корисна, тому що запобігти випадковій зміні глобального об'єкта коли ви думали, що працюєте з іншим контекстом. Багато типових помилок із `this` виявляються, коли ви активуєте 'use strict', саме тому, що вони перестають "працювати наполовину" та швидко дають збій.

  Альтернативи та доповнення WordArt: повний та практичний посібник

Ще однією важливою деталлю є те, що в глобальному середовищі браузера, Змінні, оголошені за допомогою var, стають властивостями глобального об'єктаТаким чином, якщо ви оголосите `var nombreGlobal = 'Usuario'`, ви зможете отримати доступ до `window.nombreGlobal`. Це змішується з `this` у нестрогих функціях і призводить до цікавої (а іноді й небезпечної) поведінки.

Стрілка функціонує як «переломний момент» у цьому питанні.

Велика перевага стрілкових функцій полягає в тому, що вони не генерують нового цьогоНатомість вони захоплюють атрибут `this` області видимості, де вони створені. Простіше кажучи: `this` всередині стрілкової функції є тим самим `this`, що й зовні..

Це вирішує багато класичних проблем, де втрачався контекст, наприклад, у зворотних викликах forEach, setTimeout, слухачах та промісах. Більше немає потреби прив'язуватися до кожного внутрішнього зворотного виклику або переносити проміжні змінні, такі як self або that, для збереження контексту.

Дуже типовим прикладом є перебір масиву членів в об'єкті team. Якщо ви використовуєте звичайну функцію всередині `forEach`, `this` переривається і не вказує на об'єкт team. Якщо ви замість цього використовуєте стрілкову функцію, Це залишається зовнішнім методомТож ви можете прочитати this.name без жодних несподіванок.

Глобальний контекст, методи об'єктів та стрілкові функції

Функції зі стрілками поводяться по-різному залежно від контекст, у якому вони визначені:

  • Якщо вони визначені в глобальній області видимості, вони успадковують this глобальний об'єкт (об'єкт window або module залежно від середовища).
  • Якщо вони визначені у рамках звичайного методуВони успадковують `this` цього методу, який зазвичай буде об'єктом, що його викликав.
  • Якщо ви розмістите стрілку безпосередньо як метод об'єкта (myObj.method = () => {}), Такий об'єкт не отримаєшале зовнішнє this (глобальне або модуля).

Цей останній пункт є вирішальним: Не варто використовувати стрілкові функції як методи об'єкта, коли ви залежите від `this` для доступу до властивостей об'єкта.У таких випадках бажано використовувати класичний синтаксис функцій у методі, щоб `this` було об'єктом.

Натомість, гарною практикою є використання стрілкові функції, вкладені у звичайні методи коли вам потрібні зворотні виклики, що враховують `this` цього методу (наприклад, у `forEach`, `map`, `setTimeout`...).

Класи ES6, функції this та стрілки

Класи ES6 – це не що інше, як синтаксичний цукор у системі прототипів та конструкторівАле вони допомагають краще структурувати код. У класі конструктор поводиться як традиційний конструктор функцій: `this` вказує на щойно створений екземпляр.

Методи, визначені як мійМетод() { … } Вони також використовують `this` як екземпляр при виклику з об'єкта. Однак, якщо ви витягнете метод і збережете його у змінній без прив'язки, ви знову втратите контекст, як і з будь-якою іншою звичайною функцією.

Дуже популярна стратегія полягає у визначенні деяких методів класу як властивості зі стрілковою функцієюНаприклад, getInfoArrow = () => { … }. Ці методи «прив’язані» до екземпляра з моменту його створення, тому навіть якщо ви передасте їх як зворотні виклики або витягнете їх з контексту, Це й надалі правильно вказуватиме на об'єкт.Це часто використовується у фреймворках, таких як React (з компонентами класу), щоб уникнути необхідності прив'язки в конструкторі для кожного обробника подій.

Події DOM, зворотні виклики та типові проблеми з `this`

У браузері, коли ви додаєте слухач подій за допомогою addEventListener та передаєте звичайну функцію, `this` в обробнику вказує на елемент DOM, який ініціював подіюІноді це корисно, але іноді це порушує контекст вашого класу чи об'єкта.

Наприклад, якщо в класі Button ви виконуєте `this.element.addEventListener('click', this.handleClick)`, то під час спрацьовування події `this` в `handleClick` буде елементом DOM, а не екземпляром класу. Щоб виправити це, у вас є три поширені варіанти:

  • Використовуйте зв'язати(це) під час реєстрації слухача.
  • Передайте функцію-стрілку, яка викликає this.handleClick(), таким чином успадковуючи this від екземпляра.
  • Визначте handleClick як властивість зі стрілковою функцією в класі.

Щось подібне відбувається з зворотними викликами масивів (map, filter, forEach…): якщо передати метод без прив’язки, можна втратити контекст. Знову ж таки, Стрілкові функції дуже зручні для написання внутрішніх зворотних викликів, які бачать відповідне `this`. без необхідності ручного підключення.

Асинхронні операції, обіцянки та асинхронізація/очікування

З async/await, значення цього зберігається цілком природним чином в асинхронному методі, якщо ви використовуєте звичайні функції в методі класу.

Однак, коли ви об'єднуєте обіцянки з `then` та `catch`, якщо ви використовуєте звичайні функції всередині цих методів, ви ризикуєте втратити атрибут `this` екземпляра. Ось чому так часто пишуть .then(дані => цей.процес(дані)) y .catch(помилка => this.manageError(помилка))Стрілкові функції гарантують, що `this` продовжуватиме вказувати на початковий об'єкт.

У кінцевому рахунку, У сучасному асинхронному коді стрілкові функції є стандартним інструментом для підтримки контексту. без необхідності всюди приковувати ланцюги.

Коли доречно використовувати стрілкові функції

Функції зі стрілками особливо добре працюють у таких випадках:

  • Короткі зворотні виклики у методах масивів, промісах, таймерах тощо.
  • Невеликі та прості функції де ви надаєте пріоритет стислості над можливістю повторного використання цього.
  • Ситуації, коли Ви хочете, щоб це залишалося тим, що із зовнішнього середовища?, наприклад, у межах класу або методу об'єкта.
  • Компоненти класу в React та подібних бібліотеках, для уникнути необхідності прив'язки в конструкторі для кожного обробника.
  Як покроково перевірити версію ядра в Windows 11

Крім того, в Програмування Більш функціональні (композиція функцій, лікування, перетворення даних), стрілкові функції роблять код набагато читабельнішим та виразнішим, оскільки Вони надають перевагу чистим та коротким функціям без необхідності називати їх.

Коли НЕ слід використовувати стрілкові функції

Також є чіткі сценарії, в яких Використання стрілкових функцій — не найкраща ідея. і класична функція є кращою:

  • Методи об'єктів що залежать від `this` для доступу до властивостей об'єкта. Якщо ви визначите метод як `arrow`, `this` буде не об'єктом, а зовнішнім контекстом.
  • БудівельникиСтрілкові функції не можна використовувати з new, тому вони не корисні для створення екземплярів.
  • Функції, які потребують об'єкта arguments Стрілкові функції не мають власних аргументів; якщо вони вам потрібні, використовуйте звичайну функцію або параметри-залишки (…args).
  • Чисті утиліти або помічники контекстно-незалежний

Допоміжні функції (formatCurrency, calculateTax, невеликі математичні операції) Вони не повинні від цього покладатисяУ цих випадках важливо, щоб вони були чистими, легкими для тестування та без побічних ефектів. Ви можете писати їх за допомогою `function` або `arrow`, але взагалі уникайте покладатися на `this`.

У шаблонах функціонального програмування також рекомендується, щоб функції не залежали від контексту. Чим менше ви використовуєте `this` у цьому типі коду, тим більш передбачуваним та компонованим він буде. ваша кодова база.

Це в сучасних середовищах: React та Node.js

У React з компонентами класу використання `this` є критично важливим для обробки стан та реквізитОбробникам подій потрібен доступ до `this.setState` та властивостей компонента. Якщо ви не прив’яжете або не використаєте стрілкові функції для цих обробників, ви зіткнетеся з помилками `this undefined`, щойно користувач клацне.

Ось чому ви побачите такі візерунки в багатьох проектах handleChange = (подія) => { … } y onClick={this.handleChange}Ці стрілкові функції визначені як властивості класу. Вони автоматично пов'язані з екземпляром, уникаючи додаткових прив'язок у конструкторі та зменшуючи ризик контекстних помилок.

У Node.js поведінка `this` на рівні модуля Це не те саме, що в браузері.На рівні файлу `this` зазвичай вказує на `module.exports` (у CommonJS) або не визначено в модулях ES, а не на глобальний об'єкт. Це впливає на те, як ви розумієте `this` під час написання бібліотек та модулів повторного використання.

У будь-якому разі, правило залишається незмінним: Стрілкові функції успадковують властивість `this` від середовища, де вони визначені.У Node це буде модуль або клас, у якому ви знаходитесь, що визначає, як ви проектуєте свої API та як ви надаєте методи іншим файлам.

Використання JavaScript у середовищах, таких як Appsmith

На лоукодових/безкодових платформах, таких як Appsmith, ви можете писати JavaScript майже в будь-якій властивості віджета (текст, колір, видимість, вимкнено тощо) за допомогою виразів у {{ }}. Там обчислюються JS-вирази, які завжди повертають значення: рядок, число, логічне значення, об'єкт тощо.

Ви також можете визначити звичайні функції, вирази та стрілкові функції в JSObjectsЦе блоки коду JavaScript з `export default { … }`. Важливо зазначити, що на верхньому рівні JSObject ви визначаєте властивості та методи як пари ключ:значення, розділені комами, і що `this` цих методів поводиться залежно від того, чи є вони класичними функціями, чи стрілковими функціями.

Як найкраща практика в JSObjects, поширеною є використовувати звичайні функції як основні методи (щоб уникнути плутанини з `this`) та вкладені стрілкові функції всередині цих методів як зворотні виклики для фільтрів, карт, скорочень тощо. Цей шаблон дозволяє скористатися перевагами компактного синтаксису стрілок, не ускладнюючи обробку контексту.

Найкращі практики для опанування цієї та стрілкових функцій

Щоб отримати максимальну віддачу від цих інструментів, не зводячи їх з розуму, варто вивчити кілька порад:

  • Будьте чіткими в контекстіЯкщо ви сумніваєтеся, використовуйте функції bind або стрілочні функції, щоб чітко вказати, який саме `this` ви хочете використовувати.
  • Використовуйте стрілкові функції для зворотних викликів майже завжди, особливо в асинхронному коді та методах масивів, щоб уникнути втрати зовнішнього `this`.
  • Не змішуйте стилі без потребиЯкщо ви використовуєте стрілкові методи для обробників у класі, збережіть цей шаблон у всьому компоненті для узгодженості.
  • Активуйте «використовувати суворо» або використовувати середовища, які вже застосовують суворий режим, щоб помилки в ньому виникали швидше.
  • Уникайте покладання на «це» для корисних функційЧим вони чистіші, тим легше їх тестувати та використовувати повторно.

Добре розумію як і коли використовувати стрілкові функції, і що означає їхня лексична поведінкаЦе, разом із правилами зв'язування регулярних функцій, дає вам набагато кращі можливості для написання сучасного JavaScript. З практикою ви перестанете сприймати «this» як підступного ворога і натомість побачите в ньому потужний інструмент, який ви можете легко опанувати в будь-якому контексті, від браузера до Node.js або фреймворків, таких як React.