Стрелочные функции, которые появились в стандарте ES6 (ECMAScript 2015), призваны упростить написание кода и облегчить жизнь JavaScript-программисту. Они позволяют значительно сократить запись функции и по другому работают с контекстом в плане использования ключевого слова this.

Синтаксис стрелочной функции в JavaScript

Синтаксис стрелочной функции предполагает, что есть 2 разновидности таких функций: с краткой или блочной формой записи.

Ни в краткой, ни в блочной форме нельзя переносить стрелку на новую строку.

Давайте рассмотрим различные примеры стрелочных функций. Будем это делать, используя синтаксис, привычный в ES5 и ранее, а затем - его аналог в виде стрелочной функции ES6.

Начнем разбор синтаксиса с очень простой функции, которая выводит диалоговое окно alert() и не принимает никаких параметров. Для того чтобы иметь возможность вызвать функцию, необходимо перед ее вызовом дать ей имя в виде переменной.

В примере вы вызовете эти функции при клике на соответствующей кнопке.

Если посмотреть на синтаксис стрелочной функции по сравнению с привычной нам, то можно увидеть, что они похожи, особенно если сравнивать синтаксис function expression. Нужно просто убрать ключевое слово function и фигурные скобки, а также добавить после круглых скобок оператор =>, благодаря которому функции в ES6 и получили название стрелочных. Сразу оговорюсь, что удаление фигурных скобок работает только для функций с одной строкой кода.

Немного модифицируем вывод сообщения. Теперь мы будем отображать некую строку в <p id="mes">...</p>. Запускать функции будем по клику на кнопке. Для того, чтобы увидеть отличия, зададим разный текст для параметра message, а в самой функции укажем в стилях разный цвет для выводимого текста.

Тестируем пример:

Здесь выводим сообщение

Видим, что функции похожи, только для стрелочной отсутствует ключевое слово function и фигурные скобки. Параметр message мы передали в круглых скобках и в первой, и во второй функции. На самом деле в стрелочной функции мы могли обойтись даже без круглых скобок для параметра, если он один:

Теперь рассмотрим функцию, которая возводит передаваемое число в квадрат. В ней у нас не только появился параметр, но есть ещё и возвращаемое значение:

Как вы видите, в стрелочной функции мы обошлись и без круглых скобок, и без ключевого слова return.

Внимание! Если аргументов у функции нет, пустые круглые скобки при ее вызове обязательны!

Давайте посмотрим на результат. Недоверчивые могут проверить на калькуляторе:

Теперь рассмотрим, как можно вернуть с помощью 2-х разных функций литерал объекта:

Если в этом случае мы оставим одни фигурные скобки, то получим в консоли ошибку:

Ошибка при выводе литерала массива

Поэтому исправляем синтаксис стрелочной функции, добавив круглые скобки вокруг фигурных:

Видим теперь результат в консоли без ошибок:

Вывод литерала объекта из функцииРассмотрим еще один вариант стрелочной функции, в которой у нас есть не одна, а две или более строки кода:

Такая функция имеет вид блока кода, поэтому ее тело обязательно помещается в фигурные скобки.

Смотрим, что получится (заменяем console.log() на document.write()):

Ключевое слово this и контекст вызова функции

Камнем преткновения в JavaScript всегда было обращение к ключевому слову this внутри объектов и обработчиков событий при вызове метода setTimeout() для выполнения отложенного действия.

Стрелочные функции не имеют своего this, поэтому берут его значение из окружающего контекста (так называемое лексическое значение). Это означает, что this используется из кода, содержащего стрелочную функцию. Все остальные функции в JavaScript получают значение this динамически в зависимости от того, какой объект вызывает эту функцию.

Если рассматривать использование setTimeout() внутри обработчика события, то мы получим ошибку при использовании такого кода:

Посмотрите на скриншот консоли браузера:

Ошибка в обработчике события при вызове метода setTimeout()

Проблема в том,  что в данном случае this меняется в зависимости от того, какой объект позволяет использовать свой метод. На скриншоте выше видно, что при клике на объекте контекстом this будет div, а затем при вызове метода  setTimeout() - глобальный объект window, которому этот метод, собственно, и принадлежит.

Заменим привычную функцию на стрелочную при вызове метода setTimeout() и получим другой результат (дождитесь, пока пройдет секунда, заданная в setTimeout()):

Отобразить блок
Хорошего вам настроения!

Код теперь такой:

стрелочная функция при вызове setTimeout()Загляните сами в консоль - там и в первом, и во втором случае будет <div id="trigger"></div>.

Вторым способом, кроме использования стрелочной функции, является применение метода bind() для связывания this и определенного объекта при вызове setTimeout() или обработке событий.

Внимание: не стоит использовать стрелочную функцию в качестве обработчика события, т.к. this она возьмет из ближайшего окружения, и результат будет не таким, как вы ожидаете (см. пример ниже).

Метод объекта и this в стрелочной функции

Еще выгоду от использования this в стрелочной функции можно увидеть при использовании некоторых функций при создании объектов. Например, у нас есть такой код в стандарте ES5 и ниже.

В консоли мы увидим, что у нас this.name либо отображает объект Window, либо воспринимается как undefined в строгом режиме (раскомментируйте строку //"use strict";, чтобы посмотреть)

this в методе объекта

Ранее для выходя из этой ситуации использовалась дополнительная переменная для сохранения текущего значения this, например, _this, that или self. Код перепишем так:

В консоли увидим уже другой результат: значения для this и self будут отличаться.

Замена this на self

Второй способ решения этой проблемы - в использовании this, который можно задать для некоторых методов массива вроде forEach(), map(), filter(), some(), every() в качестве второго, необязательного аргумента после вызова callback-функции.

Переписываем код еще раз:

Получаем четкое обращение к нашему объекту Pizza на каждом этапе:

this из метода map()

Такой же вариант в консоли мы получим, использовав стрелочную функцию. Уберем из нее вывод console.log() для уменьшения кода. Наша функция возьмет контекст объекта Pizza и избавит нас от мучений. Результирующая функция будет такой:

Просто и красиво, не так ли? Все-таки, краткость - сестра таланта, а стрелочные функции - любимчики JS-программистов.

Стрелочная функция как метод класса

Классы в JavaScript появились также в стандарте ES6 (ECMAScript2015), поэтому логично было бы попробовать использовать стрелочные функции внутри класса в качестве одного из методов (но не в качестве конструктора).

Создадим простой класс User, в ктором используем стрелочную функцию для вывода информации о пользователе.

Поскольку метод printName() объявлен внутри класса, то и ключевое слово this будет относится к любому экземпляру данного класса, созданного с помощью конструктора new User().

Посмотрим на пример в действии:

Следует отметить, что стрелочные функции часто используются в таких библиотеках, как React или Vue.js, т.к. используют контекст класса.

Использование стрелочных функций в качестве callback-ов

Callback-функции, или функции обратного вызова, очень часто сейчас используются для работы с массивами, а точнее с их методами forEach(), map()reduce(). Лучше всего видно сокращение количества кода в тех методах, которые что-либо возвращают. Например, нам нужно записать в отдельный массив длину строк элементов существующего массива. Сравните, насколько короче будет запись в формате стрелочной функции:

Посмотрим на вывод массива с помощью array.foEach(). Работа старого и нового синтаксиса отличается цветом текста.

Чего нельзя делать с помощью стрелочных функций:

  1. Стрелочные функции нельзя использовать в качестве конструкторов объектов, т.е. с ними нельзя использовать оператор new:

    В консоли выведется сообщение:
    Ошибка при создании объекта
  2. Нельзя использовать  стрелочные функции в виде метода или прототипа объекта.
  3. Нельзя применить такие методы, как Message.bind(), Message.call(), Message.apply(), т.к. в стрелочных функциях мы не можем изменить значение this, которое в них всегда берется из контекста.
  4.  В стрелочных функциях нет массива arguments
  5. Нельзя использовать стрелочные функции напрямую для обработки событий в том случае, если в функции вы обращаетесь к объекту через ключевое слово this:

    Клик по тексту сменит его цвет

    При клике на элементе вы не увидите синего текста, т.к. стрелочная функция выдаст нам ошибку:
    Ошибка при использовании стрелочной функции в качестве обработчика события
    Если же вы будете использовать другое обращение к элементу или делегирование событий через event.target, или при использовании объекта события event и его свойств или методов, то стрелочные функции будут работать вполне корректно. Например:

    Пример можно посмотреть в отдельной вкладке или в статье "Создание html-элементов в JavaScript".
  6. Стрелочные функции, в отличие от обычных, не имеют своего this и значений super .
Автор: Админ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *