Стрілкові функції (Arrow functions) у ECMAScript 6
У загальному випадку, синтаксис стрілочних функцій виглядає так:
Він дуже схожий на аналогічний синтаксис у таких мовах як Scala, CoffeeScript та на синтаксис lambda-виразів з C#.
Синтаксис стрілочних функцій може бути різним, залежно від того, як ви оголошуєте функцію. Оголошення завжди починається зі списку аргументів, далі слідує стрілка та тіло функції. І список аргументів, і тіло функції можуть мати різну форму залежно від того, що ви пишете.
Один параметр
Оголошення стрілочної функції, яка приймає один аргумент і просто повертає його, виглядає дуже просто:
Коли у стрілочної функції лише один аргумент, він може бути оголошений без дужок. Наступне після стрілки тіло функції може бути без фігурних дужок і може не містити ключового словаreturn.
Декілька параметрів
Але якщо ви хочете оголосити більше одного параметра, то маєте обрамити список параметрів у круглі дужки:
Функція sum просто підсумовує два аргументи. Єдина відмінність від попереднього прикладу в наявності круглих дужок та коми (прямо як у традиційних функціях).
Без параметрів
Аналогічно, функція без жодних аргументів повинна мати порожній список параметрів, укладений у круглі дужки:
Традиційний синтаксис тіла функції
Ви можете скористатися синтаксисом традиційних функцій для тіла стрілочної функції, коли воно містить більше одного виразу. Тобто обернути функцію у фігурні дужки та додати ключове словоreturn :
Тіло функції буде оброблено точно так, як і у випадку класичних функцій, за винятком того, що значення спеціальних зміннихthis,super іarguments будуть обчислюватися по-іншому.
Літерал об'єкту
Окремо треба згадати, що тіло функції, яке не містить фігурних дужок і просто повертає літерал об'єкта, має бути забрано в круглі дужки:
Приміщення літерала об'єкта в круглі дужки вказує парсеру, що фігурні дужки це початок традиційного синтаксису для тіла функції, а початок літерала.
Змінна кількість параметрів
Так як «власний» об'єктarguments не доступний всередині стрілочної функції (значенняarguments лексично пов'язане зі значеннямarguments традиційної функції, усередині якої стрілочна функція була оголошена), то для стрілочних функцій зі змінним числом параметрів потрібно використовуватиrest -патерн із шаблонів деструктуризації. Приклад:
Шаблон деструктуризації як параметр
Як видно з попереднього прикладу, незважаючи на те, що у стрілочної функції лише один аргумент, все одно необхідно застосовувати круглі дужки при використанні шаблонів деструктуризації як єдиного параметра функції. Приклади з іншими шаблонами:
Використання стрілочних функцій
Встановлення контексту
У наведеному коді об'єкт pageHandler повинен обробляти кліки на сторінці. Метод init() навішує обробник на потрібну подію, який у собі викликає this.doSomething() . Проте код відпрацює неправильно. Посилання на this.doSomething() не валідна, оскількиthis вказує на об'єкт document всередині обробника події замість запланованого pageHandler . При спробі виконати цей код ви отримаєте помилку, оскільки об'єкт document не має методу doSomething .
Ви можете зав'язати значенняthis на об'єкті pageHandler, використовуючи handleEvent або викликавши у функції стандартний метод bind() :
Теперкод працює так, як і думалося, але виглядає більш громіздко. Крім того, викликаючи bind(this) ви щоразу створюєте нову функцію, значенняthis якої зав'язане на значенні pageHandler , але код працює так, як ви задумували.
Стрілецькі функції вирішують проблему більш елегантним способом, оскільки використовують лексичне зв'язування значенняthis (а такожsuper іarguments ) і його значення визначається значеннямthis > у тому місці, де стрілочна функція була створена. Наприклад:
У цьому прикладі обробник це стрілочна функція в якій викликається this.doSomething() . Значенняthis буде тим самим, що і функції init() , і код в даному прикладі відпрацює правильно, аналогічно тому, який використовував bind() . Незалежно від того, чи повертає виклик this.doSomething() значення чи ні, вираз усередині тіла стрілочної функції не потрібно обрамляти у фігурні дужки.
Крім того, приклад вищий ще й ефективніший за виклик bind() , тому що для браузера він аналогічний наступному коду:
Тобто не відбувається створення нової функції, як у разі виклику bind() .
"Прокидання" контексту між кількома викликами
Очевидно, що можна вкладати одну стрілочну функцію в іншу, тим самим прокидаючи значенняthis через них:
Використання як аргумент
Короткий синтаксис стрілочних функцій робить їх ідеальними кандидатами на передачу як аргументи виклик інших функцій. Наприклад, якщо ви хочете відсортувати масив, то зазвичай пишете щось на кшталт такого:
Досить багатослівно для простої операції. Порівняйте з коротким записом стрілочної функції:
Використання таких методів, як масивні sort() , map() , reduce() і так далі, можебути спрощено з використанням короткого синтаксису стрілочної функції.
Інші особливості стрілочних функцій
Незважаючи на те, що стрілочні функції відрізняються від традиційних функцій, вони мають спільні риси:
- Оператор типуповерне "функцію" для стрілочної функції
- Стрілочна функція також екземпляр «класу» Function, тому instanceof спрацює так само, як і з традиційною функцією
- Ви все ще можете використовувати методи call() , apply() і bind() , однак пам'ятайте, що вони не будуть впливати на значенняthis
- Ви можете використовувати метод toMethod() , однак він не змінюватиме значенняsuper (метод toMethod() введений в es6 і не розглядається в рамках цієї статті).
Стрілецькі функції це одне з найцікавіших нововведень в ECMAScript 6, яке, маючи короткий синтаксис визначення, спростить передачу функцій значення параметра іншої функції.
Короткий синтаксис дозволить писати складні речі ще складніше простіше. Наприклад, так буде виглядати генератор ідентифікаторів (який на es5 виглядає куди багатослівнішим):
Також ви можете спробувати стрілочні функції та інші можливості es6 в онлайн-трансляторі Traceur.