Анонимные и стрелочные функции
Давайте поближе познакомимся с анонимными функциями, то есть, с функциями, у которых нет имени:
Но просто объявить такую функцию нельзя, возникнет ошибка выполнения такого кода. Это легко поправить, если присвоить эту функцию какой-либо переменной:
Теперь ошибки синтаксиса возникать не будет. Мало того, мы теперь можем даже вызвать эту функцию через переменную anonym:
Вспоминаем этот синтаксис: чтобы вызвать какую-либо функцию, после ее имени нужно записать круглые скобки. После выполнения мы в консоле увидим сообщение «это анонимная функция».
Этот же синтаксис прекрасно сработает и с именованной функцией, например, так:
Правда, если мы попробуем вызвать функцию по ее второму имени:
то возникнет ошибка, что func не определена. Дело в том, что по приоритетам в глобальной области видимости (то есть, вне функции) будет существовать только переменная anonym, но не переменная func. Имя func существует только внутри самой функции, за ее пределами такого имени уже нет.
Вернемся к анонимной функции. Можно ли ее вызвать, не присваивая ее переменной? Оказывается, можно. Для этого поместим функцию в круглые скобки и в конце поставим еще одни круглые скобки для ее вызова:
Обратите внимание, чтобы этот код сработал, после директивы “use strict” нужно поставить точку с запятой. Без точки с запятой интерпретатор будет полагать, что мы прописываем аргумент у строки “use strict” и получим синтаксическую ошибку.
Теперь наша функция вызывается непосредственно в том месте, где объявлена. Это называется функциональным выражением. То есть, когда интерпретатор встречает такую запись, он немедленно выполняет код, находящийся внутри анонимной функции. Функция вызывается благодаря круглым скобкам, записанным после ее объявления. Как пример, такие функции часто используют как аргументы callback-функций, о которых мы немного говорили на прошлом занятии. Приведу здесь еще один пример. Вызовем анонимную функцию через секунду после запуска скрипта. Это делается с помощью стандартной JavaScript-функции setTimeout:
Здесь первый агрумент – это callback-функция, а второй – задержка исполнения в миллисекундах (1000 мс = 1 сек).
Стрелочные функции
В новой спецификации стандарта языка JavaScript – ES6 вводится понятие стрелочных функций. Это такое развитие или, скорее, упрощение анонимных функций. Что это такое? Представим, что у нас вот такая анонимная функция:
Преобразуем ее в стрелочную. Уберем ключевое слово function, а вместо фигурных скобок запишем вот такие символы => — очень похоже на стрелку.
Предыдущую функцию закомментируем. Все, получили стрелочную функцию. Ее можно вызвать через переменную anonym и она будет работать аналогично закомментированной анонимной функции.
Возможно, такая запись функции выглядит несколько необычно? Но это дело привычки. В дальнейшем она будет также хорошо восприниматься как и обычные функции.
Но особенности стрелочных функций на этом не заканчиваются. Предположим, мы хотим, чтобы такая функция возвращала какой-либо результат. В обычных функциях для этого используется оператор return. Здесь это делается несколько иначе. Давайте возвратим стрелочной функцией строку, которая выводилась в консоль. Для этого ее нужно записать так:
Смотрите как элегантно это выглядит. Если мы хотим что-то вернуть, то просто пишем возвращаемое выражение после стрелки. И никакого оператора return! Мало того, его здесь даже нельзя прописать – будет синтаксическая ошибка. Это все работает только в таком виде. То есть, когда телом стрелочной функции выступает какое-либо одно выражение (в данном случае – это строковый литерал), то записывая его без фигурных скобок, оператор return подразумевается.
Как пример можно записать и такое выражение:
Увидим в консоле результат суммы – число 78. И так далее. Но, если мы поместим тело функции в фигурные скобки, то возврат уже работать не будет:
Мы получим значение undefined, как правило, означающее, что функция ничего не возвращает. Чтобы все работало, оператор return здесь обязателен:
Фигурные скобки в стрелочных функциях используются, если тело функции содержит более одного выражения:
Здесь фигурные скобки обязательны и без них код работать уже не будет.
Далее, стрелочным функциям можно передавать аргументы, как и обычным функциям. И, как вы наверное уже догадались, они прописываются внутри круглых скобок, например, так:
Смотрите, как просто можно записать стрелочную функцию для сложения двух значений. Кстати, если функция принимает один параметр, то круглые скобки можно не прописывать:
Во всех других случаях круглые скобки обязательны:
Стрелочные функции, несмотря на всю их простоту, имеют свои особенности. Например, у них нет своего контекста при их вызове, как у обычных функций. И они чаще всего используются в ООП. Но обо всем этом пока не задумывайтесь, на данном этапе нужно в целом понять как они записываются и вызываются.
Видео по теме
JavaScipt #1: что это такое, с чего начать, как внедрять и запускать
JavaScipt #2: способы объявления переменных и констант в стандарте ES6+
JavaScript #3: примитивные типы number, string, Infinity, NaN, boolean, null, undefined, Symbol
JavaScript #4: приведение типов, оператор присваивания, функции alert, prompt, confirm
JavaScript #5: арифметические операции: +, -, *, /, **, %, ++, —
JavaScript #6: условные операторы if и switch, сравнение строк, строгое сравнение
JavaScript #7: операторы циклов for, while, do while, операторы break и continue
JavaScript #8: объявление функций по Function Declaration, аргументы по умолчанию
JavaScript #9: функции по Function Expression, анонимные функции, callback-функции
JavaScript #10: анонимные и стрелочные функции, функциональное выражение
JavaScript #11: объекты, цикл for in
JavaScript #12: методы объектов, ключевое слово this
JavaScript #13: клонирование объектов, функции конструкторы
JavaScript #14: массивы (array), методы push, pop, shift, unshift, многомерные массивы
JavaScript #15: методы массивов: splice, slice, indexOf, find, filter, forEach, sort, split, join
JavaScript #16: числовые методы toString, floor, ceil, round, random, parseInt и другие
JavaScript #17: методы строк — length, toLowerCase, indexOf, includes, startsWith, slice, substring
JavaScript #18: коллекции Map и Set
JavaScript #19: деструктурирующее присваивание
JavaScript #20: рекурсивные функции, остаточные аргументы, оператор расширения
JavaScript #21: замыкания, лексическое окружение, вложенные функции
JavaScript #22: свойства name, length и методы call, apply, bind функций
JavaScript #23: создание функций (new Function), функции setTimeout, setInterval и clearInterval
© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Источник
Функциональные выражения
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/function-expressions.
В JavaScript функция является значением, таким же как строка или число.
Как и любое значение, объявленную функцию можно вывести, вот так:
Обратим внимание на то, что в последней строке после sayHi нет скобок. То есть, функция не вызывается, а просто выводится на экран.
Функцию можно скопировать в другую переменную:
- Объявление (1) как бы говорит интерпретатору «создай функцию и помести её в переменную sayHi
- В строке (2) мы копируем функцию в новую переменную func . Ещё раз обратите внимание: после sayHi нет скобок. Если бы они были, то вызов var func = sayHi() записал бы в func результат работы sayHi() (кстати, чему он равен? правильно, undefined , ведь внутри sayHi нет return ).
- На момент (3) функцию можно вызывать и как sayHi() и как func()
- …Однако, в любой момент значение переменной можно поменять. При этом, если оно не функция, то вызов (4) выдаст ошибку.
Обычные значения, такие как числа или строки, представляют собой данные. А функцию можно воспринимать как действие.
Это действие можно запустить через скобки () , а можно и скопировать в другую переменную, как было продемонстрировано выше.
Объявление Function Expression
Существует альтернативный синтаксис для объявления функции, который ещё более наглядно показывает, что функция – это всего лишь разновидность значения переменной.
Он называется «Function Expression» (функциональное выражение) и выглядит так:
Сравнение с Function Declaration
«Классическое» объявление функции, о котором мы говорили до этого, вида function имя(параметры) <. >, называется в спецификации языка «Function Declaration».
- Function Declaration – функция, объявленная в основном потоке кода.
- Function Expression – объявление функции в контексте какого-либо выражения, например присваивания.
Несмотря на немного разный вид, по сути две эти записи делают одно и то же:
Оба этих объявления говорят интерпретатору: «объяви переменную sum , создай функцию с указанными параметрами и кодом и сохрани её в sum «.
Основное отличие между ними: функции, объявленные как Function Declaration, создаются интерпретатором до выполнения кода.
Поэтому их можно вызвать до объявления, например:
А если бы это было объявление Function Expression, то такой вызов бы не сработал:
Это из-за того, что JavaScript перед запуском кода ищет в нём Function Declaration (их легко найти: они не являются частью выражений и начинаются со слова function ) и обрабатывает их.
А Function Expression создаются в процессе выполнения выражения, в котором созданы, в данном случае – функция будет создана при операции присваивания sayHi = function.
Как правило, возможность Function Declaration вызвать функцию до объявления – это удобно, так как даёт больше свободы в том, как организовать свой код.
Можно расположить функции внизу, а их вызов – сверху или наоборот.
Условное объявление функции
В некоторых случаях «дополнительное удобство» Function Declaration может сослужить плохую службу.
Например, попробуем, в зависимости от условия, объявить функцию sayHi по-разному:
Function Declaration при use strict видны только внутри блока, в котором объявлены. Так как код в учебнике выполняется в режиме use strict , то будет ошибка.
А что, если использовать Function Expression?
Оба этих варианта работают правильно, поскольку, в зависимости от условия, создаётся именно та функция, которая нужна.
Анонимные функции
Взглянем ещё на один пример – функцию ask(question, yes, no) с тремя параметрами:
question Строка-вопрос yes Функция no Функция
Она выводит вопрос на подтверждение question и, в зависимости от согласия пользователя, вызывает функцию yes() или no() :
Какой-то очень простой код, не правда ли? Зачем, вообще, может понадобиться такая ask ?
…Оказывается, при работе со страницей такие функции как раз очень востребованы, только вот спрашивают они не простым confirm , а выводят более красивое окно с вопросом и могут интеллектуально обработать ввод посетителя. Но это всё потом, когда перейдём к работе с интерфейсом.
Здесь же обратим внимание на то, что то же самое можно написать более коротко:
Здесь функции объявлены прямо внутри вызова ask(. ) , даже без присвоения им имени.
Функциональное выражение, которое не записывается в переменную, называют анонимной функцией.
Действительно, зачем нам записывать функцию в переменную, если мы не собираемся вызывать её ещё раз? Можно просто объявить непосредственно там, где функция нужна.
Такого рода код возникает естественно, он соответствует «духу» JavaScript.
new Function
Существует ещё один способ создания функции, который используется очень редко, но упомянем и его для полноты картины.
Он позволяет создавать функцию полностью «на лету» из строки, вот так:
То есть, функция создаётся вызовом new Function(params, code) :
params Параметры функции через запятую в виде строки. code Код функции в виде строки.
Таким образом можно конструировать функцию, код которой неизвестен на момент написания программы, но строка с ним генерируется или подгружается динамически во время её выполнения.
Пример использования – динамическая компиляция шаблонов на JavaScript, мы встретимся с ней позже, при работе с интерфейсами.
Итого
Функции в JavaScript являются значениями. Их можно присваивать, передавать, создавать в любом месте кода.
- Если функция объявлена в основном потоке кода, то это Function Declaration.
- Если функция создана как часть выражения, то это Function Expression.
Между этими двумя основными способами создания функций есть следующие различия:
Function Declaration | Function Expression | |
---|---|---|
Время создания | До выполнения первой строчки кода. | Когда управление достигает строки с функцией. |
Можно вызвать до объявления | Да (т.к. создаётся заранее) | Нет |
Условное объявление в if | Не работает | Работает |
Иногда в коде начинающих разработчиков можно увидеть много Function Expression. Почему-то, видимо, не очень понимая происходящее, функции решают создавать как var func = function() , но в большинстве случаев обычное объявление функции – лучше.
Если нет явной причины использовать Function Expression – предпочитайте Function Declaration.
Сравните по читаемости:
Function Declaration короче и лучше читается. Дополнительный бонус – такие функции можно вызывать до того, как они объявлены.
Используйте Function Expression только там, где это действительно нужно и удобно.
Источник