Что такое функции в javascript
Перейти к содержимому

Что такое функции в javascript

  • автор:

 

Функции — часть первая

Функция – это блок программного кода на языке JavaScript, который определяется один раз и может выполняться, или вызываться, многократно.

Функция представляет собой именованное объединение группы инструкций. Это объединение может быть вызвано из других частей программы.

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

Причиной, из-за которой в свое время была создана концепция функций, стало стремление сократить размер программного кода. Любая последовательность инструкций, встречающаяся в программе более одного раза, будучи вынесенной в отдельную функцию, сокращает размер программы.

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

example img

Люди считают, что компьютерные науки – это искусство для гениев. В реальности всё наоборот – просто множество людей делают вещи, которые стоят друг на друге, будто составляя стену из маленьких камушков.

2. Объявление функций

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

— Идентификатор, определяющий имя функции. Имя является обязательной частью инструкции объявления функции;
— Пара круглых скобок вокруг списка из нуля или более идентификаторов, разделенных запятыми. Эти идентификаторы будут определять имена параметров функции и в теле функции могут использоваться как локальные переменные.;
— Пара фигурных скобок с нулем или более инструкций JavaScript внутри. Эти инструкции составляют тело функции: они выполняются при каждом вызове функции.

Обратите внимание на то, что объявление функции не заканчивается точкой с запятой (;).

Объявления говорит интерпретатору о том, функция, имеющая данные атрибуты, будет вызвана позже. Информацию о функции, содержащуюся в ее объявлении также иногда называют сигнатурой функции.

3. Вызов функций

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

Вызов функций выполняется с помощью выражения вызова. Выражение вызова состоит из выражения обращения к функции, которое возвращает объект функции, и следующими за ним круглыми скобками со списком из нуля или более выражений-аргументов, разделенных запятыми, внутри.

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

4. Аргументы и параметры функций

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

В языке JavaScript, в определениях функций не указываются типы параметров, а при вызове функций не выполняется никаких проверок типов передаваемых значений аргументов. Фактически при вызове функций в языке JavaScript не проверяется даже количество аргументов.

Функцию можно вызвать с любым количеством аргументов. Если параметр не передан при вызове – он считается равным undefined.

4.1 Аргументы по умолчанию

Для указания значения «по умолчанию», то есть, такого, которое используется, если аргумент не указан можно использовать такой приём: проверяем равен ли аргумент undefined, и если получаем true – записываем в него значение по умолчанию.

5. Значение, возвращаемое функцией

Когда выполнение функции завершается, она может возвратить значение программе, которая ее вызвала. Как правило, возвращаемое функцией значение имеет отношение к решению задачи, возложенной на эту функцию. Следующий пример демонстрирует применение функции, получающей значение веса в фунтах и возвращающей эквивалентное значение этого веса в килограммах:

Для возврата значения используется инструкция return. Как только до неё доходит управление – функция завершается. Инструкция return может также использоваться без значения, чтобы прекратить выполнение и выйти из функции. Инструкция return может располагаться только в теле функции. Присутствие ее в любом другом месте является синтаксической ошибкой.

В коде выше, если сработал if, то строка (*) и весь код под ней никогда не выполнится, так как return завершает выполнение функции.

Если функция возвращает значение (а функция в JavaScript всегда возвращает значение), то вызов функции рассматривается как выражение, значение которого равно величине, возвращаемой функцией. Мы можем использовать это выражение аналогично любым другим выражениям; например, мы можем присвоить его значение переменной:

6. Локальные переменные

Функция может содержать локальные переменные, объявленные через var. Такие переменные видны только внутри функции:

Неважно, где именно в функции объявляется переменная. Любое объявление срабатывает один раз и распространяется на всю функцию. Такое поведение var внутри функций называется всплытие, эго мы рассмотрим позже.

7. Внешние переменные

Функция может обратиться ко внешней переменной, например:

Доступ возможен не только на чтение, но и на запись. При этом, так как переменная внешняя, то изменения будут видны и снаружи функции:

Если бы внутри функции, в строке (1), была бы объявлена своя локальная переменная var userName, то все обращения использовали бы её, и внешняя переменная осталась бы неизменной.

Более детально механизм взаимодействия c внешними переменными мы рассмотрим позже.

8. Всплытие внутри функций

Так сложилось, что одна из самых хитрых частей программирования на JavaScript — это локация и способ объявления переменных. В большинстве С-подобных языков переменные (или их связывания) создаются там, где их объявляют. Однако в JavaScript это не совсем так. Используя var объявления, переменная перемещается на начало функции (или в начало глобальной области видимости, если объявление состоялось вне функции) независимо от того, где оно произошло на самом деле — это называется всплытие. Чтобы продемонстрировать это поведение, рассмотрим следующую функцию:

Если вы не знакомы с JavaScript, скорее всего вы ожидаете, что переменная value будет создана только тогда, когда condition будет равняться true. На самом деле value будет создана независимо от этого. Под капотом движок JavaScript изменяет функцию getValue таким образом, что она выглядит так:

Переменная value всплывает вверху блока и в том же месте происходит инициализация. Это означает, что переменная value все еще доступна в блоке else. Однако, если обратиться к ней, получим undefined, потому что она еще не проинициализирована.

Часто новичкам в JavaScript-разработке трудно привыкнуть к тому, как работает объявления переменных, и непонимание этой неочевидной поведения может привести к ошибкам.

9. Именование функций

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

Чаще всего в качестве имен функций выбираются глаголы или фразы, начинающиеся с глаголов. По общепринятому соглашению имена функций начинаются со строчной буквы. Если имя состоит из нескольких слов, в соответствии с одним из соглашений они отделяются друг от друга символом подчеркивания, примерно так: like_this(), по другому соглашению все слова, кроме первого, начинаются с прописной буквы, примерно так: likeThis(). Имена функций, которые, как предполагается, реализуют внутреннюю, скрытую от посторонних глаз функциональность, иногда начинаются с символа подчеркивания.

— Имя функции должно понятно и чётко отражать, что она делает. Увидев её вызов в коде, вы должны тут же понимать, что она делает.
— Функция – это действие, поэтому для имён функций, как правило, используются глаголы.

10. Резюме

Функция – это блок программного кода на языке JavaScript, который определяется один раз и может выполняться, или вызываться, многократно.

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

Когда выполнение функции завершается, она может возвратить значение программе, которая ее вызвала. Функция может возвращать только одно значение.

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

Функции являются основными строительными блоками скриптов. Мы будем неоднократно возвращаться к ним и изучать все более и более глубоко.

11. Упражнения

1. Минимум

В предыдущей главе была упомянута функция Math.min, возвращающая самый маленький из аргументов. Теперь мы можем написать такую функцию сами. Напишите функцию min, принимающую два аргумента, и возвращающую минимальный из них.

2. Even number

Создайте функцию isEven, которая возвращает значение true или false в зависимости от того является ли аргумент x четным.

3. dayOfWeek

Создайте функцию, которая принимает в себя число x э [1; 7] и возвращает название дня недели. Используйте switch-case.

4. calcBox

Создайте функцию, которая принимает в себя 3 аргумента и рассчитывает объем коробки.

5. hmsToSecs

Напишите функцию hmsToSecs, имеющую три аргумента h, m, s. Функция должна возвращать эквивалент переданного ей временного значения в секундах. Создайте программу, которая будет циклически запрашивать у пользователя ввод значения часов, минут и секунд и выводить результат работы функции на экран.

6. callCounter

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

7. primeNumber

Напишите функцию, которая которая принимает в себя натуральное число n и возвращает самое большое простое число в диапазоне (2; n).

Love Soft

Загрузки всякие

Связь

Содержание

09 Функции

Переменные, объявленные через var внутри функции, видны везде внутри этой функции, блоки if, for и т.п. на видимость не влияют.

Неважно, где именно в функции и сколько раз объявляется переменная. Любое объявление срабатывает один раз и распространяется на всю функцию.

Функция без return считается возвращающей undefined. Вызов return без значения также возвращает undefined

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

Функция может обратиться ко внешней переменной. Переменные, объявленные на уровне всего скрипта, называют глобальными переменными.

При обращении к необъявленной переменной функция будет искать внешнюю переменную с таким именем

Параметры передаются по значению.

Если параметр не передан при вызове – он считается равным undefined.

При объявлении функции необязательные аргументы, как правило, располагают в конце списка.

Если аргументов передано больше, чем надо, то ошибки не будет. Чтобы получить такие «лишние» аргументы, нужно будет прочитать их из специального объекта arguments (см. Псевдомассив аргументов «arguments»).

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

Например, во фреймворке jQuery есть функция $ , во фреймворке Prototype – функция $$, а в библиотеке LoDash очень активно используется функция с названием из одного символа подчеркивания _.

Примеры

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

Сделайте функцию getDigitsSum, которая параметром принимает целое число и возвращает сумму его цифр. Приведение типов:

Сделайте функцию getDivisors, которая параметром принимает число и возвращает массив его делителей (чисел, на которое делится данное число). Решение:

Дан массив с числами. Выведите последовательно его элементы используя рекурсию и не используя цикл.

Анонимные функции

Анонимную функцию можно создать и тут же вызвать с необходимыми параметрами:

Так как функция это вполне себе объект, то её можно присвоить переменной, и (или) передать в качестве параметра в другую функцию:

Функциональные выражения

В JavaScript функция является значением, таким же как строка или число.

Как и любое значение, объявленную функцию можно вывести, вот так:

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

Скобки есть — вызов функции и возврат значения, скобок нет — возврат самой функции как объекта.

Такое объявление называется Function Expression (функциональное выражение):

Классическое объявление функции вида function имя(параметры) <…>, называется в спецификации языка Function Declaration.

Основное отличие между ними: функции, объявленные как Function Declaration, создаются интерпретатором до выполнения кода.

Поэтому их можно вызвать до объявления, например:

JavaScript перед запуском кода ищет в нём Function Declaration (их легко найти: они не являются частью выражений и начинаются со слова function) и обрабатывает их.

А Function Expression создаются в процессе выполнения выражения, в котором созданы

Function Declaration при use strict видны только внутри блока, в котором объявлены. Пример:

А вот так будет работать — в зависимости от условия, создаётся именно та функция, которая нужна:

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

Действительно, зачем нам записывать функцию в переменную, если мы не собираемся вызывать её ещё раз? Можно просто объявить непосредственно там, где функция нужна.

new Function

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

Он позволяет создавать функцию полностью «на лету» из строки, вот так:

То есть, функция создаётся вызовом new Function(params, code)

Таким образом можно конструировать функцию, код которой неизвестен на момент написания программы, но строка с ним генерируется или подгружается динамически во время её выполнения.

Named Function Expression

Именованные функциональные выражения

Обычное функциональное выражение:

Именованное с именем sayHi:

Что же это за имя, которое идёт в дополнение к f, и зачем оно?

Имя функционального выражения (sayHi) имеет особый смысл. Оно доступно только изнутри самой функции (f). Как правило, имя используется для единственной цели – позволить изнутри функции вызвать саму себя.

Пример с факториалом:

Ошибка возникла потому что функция из своего кода обращается к своему старому имени f. А этой функции уже нет, f = null.

Для того, чтобы функция всегда надёжно работала, объявим её как Named Function Expression:

Псевдомассив аргументов "arguments"

В JavaScript нет «перегрузки» функций

Может быть только одна функция с конкретным именем, которая вызывается с любыми аргументами.

А уже внутри она может посмотреть, с чем вызвана и по-разному отработать.

В JavaScript любая функция может быть вызвана с произвольным количеством аргументов.

выведем список всех аргументов:

В старом стандарте JavaScript псевдо-массив arguments и переменные-параметры ссылаются на одни и те же значения.

В результате изменения arguments влияют на параметры и наоборот.

В современной редакции стандарта это поведение изменено. Аргументы отделены от локальных переменных

arguments – это не массив

В действительности, это обычный объект, просто ключи числовые и есть length. На этом сходство заканчивается. Никаких особых методов у него нет, и методы массивов он тоже не поддерживает.

Такие объекты иногда называют «коллекциями» или «псевдомассивами».

Напишите функцию sum(…), которая возвращает сумму всех своих аргументов:

Аргументы по умолчанию через ИЛИ

Если функция вызвана с меньшим количеством аргументов, чем указано, то отсутствующие аргументы считаются равными undefined.

Зачастую в случае отсутствия аргумента мы хотим присвоить ему некоторое значение «по умолчанию». Это можно удобно сделать при помощи оператора логическое ИЛИ ||.

Это отлично работает в тех ситуациях, когда «нормальное» значение параметра в логическом контексте отлично от false.

Именованные аргументы

Именованные аргументы – альтернативная техника работы с аргументами, которая вообще не использует arguments.

Некоторые языки программирования позволяют передать параметры как-то так: f(width=100, height=200), то есть по именам, а что не передано, тех аргументов нет. Это очень удобно в тех случаях, когда аргументов много, сложно запомнить их порядок и большинство вообще не надо передавать, по умолчанию подойдёт.

В JavaScript для этих целей используется передача аргументов в виде объекта, а в его свойствах мы передаём параметры.

Вызвать такую функцию очень легко. Достаточно передать объект аргументов, указав в нем только нужные:

Функции в JavaScript и классический способ их создания

Функции в JavaScript и классический способ их создания

Функция – это фрагмент кода, который можно выполнить многократно в разных частях программы. Т.е. одни и те же действия много раз с разными исходными значениями.

В следующем примере имеются повторяющиеся блоки кода, которые можно вынести отдельно в JavaScript функцию:

Повторяющие блоки кода, которые можно вынести в JavaScript функцию

Функция sum , в которую вынесен повторяющийся блок кода. После этого в местах программы, в которых его нужно выполнять, просто помещён вызов этой функции:

Это один из классических сценариев использования функций, который позволяет значительно упростить написание программ на JavaScript.

Кроме этого, функции позволяют структурировать код. Например, если перед вами стоит какая-то задача, то чтобы её проще написать, её можно разбить на подзадачи и оформить каждую из них в виде функции. А затем уже используя их написать финальный код. Вдобавок к этому в такой код будет проще вносить различные изменения и добавлять новые возможности.

JavaScript позволяет создавать функцию различными способами:

  • Function Declaration ;
  • Function Expression ;
  • Arrow Function .

В этой статье разберём первый классический способ, который называется Function Declaration .

Объявление и вызов функции

Операции с функцией в JavaScript можно разделить на 2 этапа:

  • объявление (создание) функции;
  • вызов (выполнение) этой функции.

1. Объявление функции. Написание функции посредством Function Declaration начинается с ключевого слова function . После чего указывается имя , круглые скобки , внутрь которых при необходимости помещаются параметры, и тело , заключённое в фигурные скобки. Имя функции ещё очень часто называют названием. В теле пишутся те действия, которые вы хотите выполнить с помощью этой функции.

При составлении имени функции необходимо руководствоваться такими же правилами, что для переменных. Т.е. можно использовать буквы, цифры (0 – 9), знаки «$» и «_». В качестве букв рекомендуется использовать английский алфавит (a-z, A-Z). Имя функции, также как и имя переменной не может начинаться с цифры.

При этом функции рекомендуется давать осмысленное название, т.е. такое, что было понятно, что она делает только исходя из её имени. Кроме этого, не нужно делать так, чтобы одна функция выполняла разные задачи. Лучше создать много различных функций, каждая из которых будет выполнять одну строго определённую задачу.

Параметры предназначены для получения значений, переданных в функцию, по имени. Их именование осуществляется также как переменных:

Параметры ведут себя как переменные и в теле функции мы имеем доступ к ним. Значения этих переменных (в данном случае firstname и lastname ) определяются в момент вызова функции. Обратиться к ним вне функции нельзя.

Если параметры не нужны, то круглые скобки всё равно указываются.

2. Вызов функции. Объявленная функция сама по себе не выполняется. Запуск функции выполняется посредством её вызова.

При этом когда мы объявляем функцию с именем, мы тем самым по сути создаём новую переменную с этим названием. Эта переменная будет функцией. Для вызова функции необходимо указать её имя и две круглые скобки, в которых при необходимости ей можно передать аргументы. Отделение одного аргумента от другого выполняется с помощью запятой.

Параметры и аргументы

Параметры , как мы уже отметили выше – это по сути переменные, которые описываются в круглых скобках на этапе объявления функции. Параметры доступны только внутри функции, получить доступ к ним снаружи нельзя. Значения параметры получают в момент вызова функции, т.е. посредством аргументов.

Аргументы – это значения, которые мы передаём в функцию в момент её вызова.

При вызове функции в JavaScript количество аргументов не обязательно должно совпадать с количеством параметров. Если аргумент не передан, а мы хотим его получить с помощью параметра, то он будет иметь значение undefined .

Передача аргументов примитивных типов осуществляется по значению . Т.е. значение переменной не изменится снаружи, если мы изменим её значение внутри функции.

Передача значения по ссылке

Очень важно отметить при работе с функциями, что когда в качестве аргумента мы указываем ссылочный тип, то его изменение внутри функции изменит его и снаружи:

В этом примере переменные someUser и user ссылаются на один и тот же объект в памяти. И когда мы изменяем объект внутри функции, то someUser тоже изменится.

При этом не рекомендуется изменять внешние относительно функции переменные. Т.е. если на вход функции мы передаём объект и хотим изменить его, то лучше создать копию этого объекта и изменять уже его. Таким образом мы не изменим внешний объект и код функции останется чистой.

Чтобы избежать изменение внешнего объекта, который мы передаем в функцию через аргумент, необходимо создать копию этого объекта, например, посредством Object.assign:

В этом примере мы внутри функции создали новый объект copyUser , который является копией объекта, переданного функции в качестве аргумента в момент её вызова. Т.е. someUser и copyUser — это разные объекты, хоть и содержащие на этапе копирования одинаковые свойства. После копирования, мы уже меняем свойство нового объекта и возвращаем его в качестве результата выполнения функции.

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

Локальные и внешние переменные

Переменные, объявленные внутри функции, называются локальными. Они не доступны вне функции. По сути это переменные, которые действуют только внутри функции.

При этом, когда мы обращаемся к переменной и её нет внутри функции, она берётся снаружи. Переменные объявленные вне функции являются по отношению к ней внешними .

Работа с аргументами через arguments

Получить доступ к аргументам в JavaScript можно не только с помощью параметров, но также посредством специального массивоподобного объекта arguments , доступ к которому у нас имеется внутри функции. Кроме этого он также позволяет получить количество переданных аргументов.

Доступ к аргументам через arguments выполняется точно также как к элементам обычного массива, т.е. по порядковому номеру:

 

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

Через цикл for. of этот пример можно записать так:

При необходимости arguments можно преобразовать в обычный массив:

В JavaScript arguments можно использовать для написания очень гибких функций, которые в зависимости от количества аргументов, и, их типа, могут выполнять одни или другие действия.

Все переменные, созданные внутри функции и её параметры, как мы уже отмечали выше, являются её локальными переменными. Они доступны только внутри неё, а также в других функциях, вложенных в неё, если там нет переменных с такими же именами. Вне функции локальные переменные не доступны:

При этом внутри функции мы имеем доступ к внешним переменных, но только к тем, которых с таким же именем нет в текущей функции:

Колбэк функции

Колбэк функция (от английского callback function) – это обычная функция, которая просто вызывается внутри другой функции. Такие функции ещё называются функциями обратного вызова. Они очень часто применяются в асинхронном коде.

Передаётся колбэк функция в другую через аргумент:

В этом примере имеются две функции:

  • cb – её будем использовать в роли колбэк функции, т.е. вызывать в fnWithCb ;
  • fnWithCb – эта функция, которая содержит параметр cbFn , он будет при её вызове принимать другую функцию (в данном случае cb ).

Таким образом, функция cb вызывается внутри функции fnWithCb . В неё она передаётся как аргумент. Без вызова fnWithCb она не вызовется, т.к. она вызывается только внутри fnWithCb .

Ещё один пример:

В этом примере у нас имеется функция setColorBody . В теле она содержит код, который устанавливает цвет фона <body> .

Далее вызывается функция setTimeout() . Она в свою очередь вызывает где-то внутри себя функцию, переданную ей в качестве первого аргумента. Причем вызывает не сразу, а через указанное количество миллисекунд. В данном случае через 3000.

Функцию setTimeout мы нигде не объявляли, т.к. она присутствует в JavaScript по умолчанию. Оня является методом глобальное объекта window в браузере и global в Node.js.

Обратите внимание, что в setTimeout мы просто передаём функцию setColorBody . Т.е. сами её не вызываем.

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

В JavaScript всё это возможно, благодаря тому, что функции являются объектами. А так как функция является объектом, её как значение можно передавать в другие функции посредством аргументов.

Функция – это объект

Функция в JavaScript, как уже было отмечено выше – это определённый тип объектов, которые можно вызывать. А если функция является объектом, то у неё как у любого объекта имеются свойства. Убедиться в этом очень просто. Для этого можно воспользоваться методом console.dir() и передать ему в качестве аргумента функцию.

Убеждаемся что функция является объектом и у неё есть свойства

На изображении показана структура функции sum . Используя точечную запись, мы например, можем получить название функции (свойство name ) и количество параметров( length ):

Узнать является ли переменная функцией можно с помощью typeof :

Например, проверим является переменная колбэк функцией перед тем её вызвать:

Возврат значения

Функция всегда возвращает значение, даже если мы не указываем это явно. По умолчанию она возвращает значение undefined .

Для явного указания значения, которое должна возвращать функция используется инструкция return . При этом значение или выражение, результат которого должна вернуть функция задаётся после этого ключевого слова.

Если return не указать, то функция всё равно возвратит значение, в данном случае undefined .

С использованием инструкции return :

Инструкции, расположенные после return никогда не выполняются:

В этом примере, функция sum возвращает число 94 и прекращает выполнение дальнейших инструкций после return . А так как работа функции закончилась, то сообщение в консоль выведено не будет.

Функция, которая возвращает функцию

В качестве результата функции мы можем также возвращать функцию.

Вызовы функции outer(3) и outer(4) возвращают одну и туже функцию, но первая запомнила, что a = 3 , а вторая — что a = 4 . Это происходит из-за того, что функции в JavaScript «запоминают» окружение, в котором они были созданы. Этот приём довольно часто применяется на практике. Так как с помощью него мы можем, например, на основе одной функции создать другие, которые нужны.

В примере, приведённом выше, мы могли также не создавать дополнительные константы one и two . А вызвать сразу после вызова первой функции вторую.

При создании таких конструкций нет ограничений по уровню вложенности, но с точки зрения разумности этим лучше не злоупотреблять.

Функцию, приведённую в коде мы можем также создать и так:

Кроме этого в качестве результата мы можем также возвратить внешнюю функцию:

Рекурсия

Функцию можно также вызвать внутри самой себя. Это действие в программировании называется рекурсией.

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

Например, использование рекурсии для вычисления факториала числа:

Пример, в котором используя рекурсию выведем числа от указанного до 10:

Перегрузка функций в JavaScript

Перегрузка функций в программировании – это возможность объявлять в одном месте несколько функций с одинаковыми именами. Отличаются такие функции друг от друга параметрами. Используется перегрузка функций для того, чтобы можно было вызвать подходящую под переданные аргументы функцию.

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

Например, того чтобы проверить имеет параметр значение или нет, мы можем проверить его значения на undefined . Узнать количества переданных аргументов функции можно через arguments.length . Определить значения параметра можно используя typeof или instanceof .

Например, создадим функцию bodyBgColor , которая будет иметь 2 режима работы. Если её вызвать без аргументов, то она будет возвращать цвет фона body . А если с текстовым аргументом, то она будет устанавливать цвет фона body .

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

Значение параметров функции по умолчанию

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

При вызове функции с одним аргументом, второму параметру будет автоматически присвоено строка ‘green’ .

Работу параметра по умолчанию можно представить так:

Пример функции addNewMessage , в которой один из параметров имеет дефолтное значение. Причем это значение будет меняться в зависимости от текущей даты:

В этом примере значение дефолтного параметра date будет определяться в момент вызова функции addNewMessage исходя из текущей даты. То есть, если вы вызовите addNewMessage() в другое время, то date будет иметь другую дату.

Остаточные параметры

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

Если при вызове функции ей передать аргументов больше, чем у нас есть параметров, то получить оставшиеся значения можно с помощью, так называемых rest patameters .

В описании параметров . nums должен всегда быть последним. Если что-то указать после него, то это вызовет ошибку:

Что такое встроенные (стандартные) функции

В JavaScript имеется огромный набор встроенных (стандартных) функций. Данные функции уже описаны в самом движке браузера. Практически все они являются методами того или иного объекта.

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

JavaScript - Вызов функции alert

Функция в JavaScript в результате своего выполнения всегда возвращает результат, даже если он явно не определён с помощью оператора return . Этот результат значение undefined .

JavaScript - Получить значение у функции, которая ничего не возвращает

Такой же результат будет получен, если для оператора return не указать возвращаемое значение.

Функции

Зачастую нам надо повторять одно и то же действие во многих частях программы.

Например, необходимо красиво вывести сообщение при приветствии посетителя, при выходе посетителя с сайта, ещё где-нибудь.

Чтобы не повторять один и тот же код во многих местах, придуманы функции. Функции являются основными «строительными блоками» программы.

Примеры встроенных функций вы уже видели – это alert(message) , prompt(message, default) и confirm(question) . Но можно создавать и свои.

Объявление функции

Для создания функций мы можем использовать объявление функции.

Пример объявления функции:

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

Наша новая функция может быть вызвана по своему имени: showMessage() .

Вызов showMessage() выполняет код функции. Здесь мы увидим сообщение дважды.

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

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

Локальные переменные

Переменные, объявленные внутри функции, видны только внутри этой функции.

Внешние переменные

У функции есть доступ к внешним переменным, например:

Функция обладает полным доступом к внешним переменным и может изменять их значение.

Внешняя переменная используется, только если внутри функции нет такой локальной.

Если одноимённая переменная объявляется внутри функции, тогда она перекрывает внешнюю. Например, в коде ниже функция использует локальную переменную userName . Внешняя будет проигнорирована:

Переменные, объявленные снаружи всех функций, такие как внешняя переменная userName в вышеприведённом коде – называются глобальными.

Глобальные переменные видимы для любой функции (если только их не перекрывают одноимённые локальные переменные).

Желательно сводить использование глобальных переменных к минимуму. В современном коде обычно мало или совсем нет глобальных переменных. Хотя они иногда полезны для хранения важнейших «общепроектовых» данных.

Параметры

Мы можем передать внутрь функции любую информацию, используя параметры.

В нижеприведённом примере функции передаются два параметра: from и text .

Когда функция вызывается в строках (*) и (**) , переданные значения копируются в локальные переменные from и text . Затем они используются в теле функции.

Вот ещё один пример: у нас есть переменная from , и мы передаём её функции. Обратите внимание: функция изменяет значение from , но это изменение не видно снаружи. Функция всегда получает только копию значения:

Значение, передаваемое в качестве параметра функции, также называется аргументом.

  • Параметр – это переменная, указанная в круглых скобках в объявлении функции.
  • Аргумент – это значение, которое передаётся функции при её вызове.

Мы объявляем функции со списком параметров, затем вызываем их, передавая аргументы.

Рассматривая приведённый выше пример, мы могли бы сказать: "функция showMessage объявляется с двумя параметрами, затем вызывается с двумя аргументами: from и "Привет" ".

Значения по умолчанию

Если при вызове функции аргумент не был указан, то его значением становится undefined .

Например, вышеупомянутая функция showMessage(from, text) может быть вызвана с одним аргументом:

Это не приведёт к ошибке. Такой вызов выведет "*Аня*: undefined" . В вызове не указан параметр text , поэтому предполагается, что text === undefined .

Если мы хотим задать параметру text значение по умолчанию, мы должны указать его после = :

Теперь, если параметр text не указан, его значением будет "текст не добавлен"

В данном случае "текст не добавлен" это строка, но на её месте могло бы быть и более сложное выражение, которое бы вычислялось и присваивалось при отсутствии параметра. Например:

В JavaScript параметры по умолчанию вычисляются каждый раз, когда функция вызывается без соответствующего параметра.

В приведённом выше примере, функция anotherFunction() не будет вызвана вообще, если указан параметр text .

С другой стороны, функция будет независимо вызываться каждый раз, когда text отсутствует.

Ранние версии JavaScript не поддерживали параметры по умолчанию. Поэтому существуют альтернативные способы, которые могут встречаться в старых скриптах.

Например, явная проверка на undefined :

…Или с помощью оператора || :

Альтернативные параметры по умолчанию

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

Во время выполнения функции мы можем проверить, передан ли параметр, сравнив его с undefined :

…Или мы можем использовать оператор || :

Современные движки JavaScript поддерживают оператор нулевого слияния ?? . Его использование будет лучшей практикой, в случае, если большинство ложных значений, таких как 0 , следует расценивать как «нормальные».

Возврат значения

Функция может вернуть результат, который будет передан в вызвавший её код.

Простейшим примером может служить функция сложения двух чисел:

Директива return может находиться в любом месте тела функции. Как только выполнение доходит до этого места, функция останавливается, и значение возвращается в вызвавший её код (присваивается переменной result выше).

Вызовов return может быть несколько, например:

Возможно использовать return и без значения. Это приведёт к немедленному выходу из функции.

В коде выше, если checkAge(age) вернёт false , showMovie не выполнит alert .

Если функция не возвращает значения, это всё равно, как если бы она возвращала undefined :

Пустой return аналогичен return undefined :

Для длинного выражения в return может быть заманчиво разместить его на нескольких отдельных строках, например так:

Код не выполнится, потому что интерпретатор JavaScript подставит точку с запятой после return . Для него это будет выглядеть так:

Таким образом, это фактически стало пустым return .

Если мы хотим, чтобы возвращаемое выражение занимало несколько строк, нужно начать его на той же строке, что и return . Или, хотя бы, поставить там открывающую скобку, вот так:

И тогда всё сработает, как задумано.

Выбор имени функции

Функция – это действие. Поэтому имя функции обычно является глаголом. Оно должно быть кратким, точным и описывать действие функции, чтобы программист, который будет читать код, получил верное представление о том, что делает функция.

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

Например, функции, начинающиеся с "show" обычно что-то показывают.

Функции, начинающиеся с…

  • "get…" – возвращают значение,
  • "calc…" – что-то вычисляют,
  • "create…" – что-то создают,
  • "check…" – что-то проверяют и возвращают логическое значение, и т.д.

Примеры таких имён:

Благодаря префиксам, при первом взгляде на имя функции становится понятным, что делает её код, и какое значение она может возвращать.

Функция должна делать только то, что явно подразумевается её названием. И это должно быть одним действием.

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

Несколько примеров, которые нарушают это правило:

  • getAge – будет плохим выбором, если функция будет выводить alert с возрастом (должна только возвращать его).
  • createForm – будет плохим выбором, если функция будет изменять документ, добавляя форму в него (должна только создавать форму и возвращать её).
  • checkPermission – будет плохим выбором, если функция будет отображать сообщение с текстом доступ разрешён/запрещён (должна только выполнять проверку и возвращать её результат).

В этих примерах использовались общепринятые смыслы префиксов. Конечно, вы в команде можете договориться о других значениях, но обычно они мало отличаются от общепринятых. В любом случае вы и ваша команда должны чётко понимать, что значит префикс, что функция с ним может делать, а чего не может.

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

Например, фреймворк jQuery определяет функцию с помощью $ . В библиотеке Lodash основная функция представлена именем _ .

Это исключения. В основном имена функций должны быть в меру краткими и описательными.

Функции == Комментарии

Функции должны быть короткими и делать только что-то одно. Если это что-то большое, имеет смысл разбить функцию на несколько меньших. Иногда следовать этому правилу непросто, но это определённо хорошее правило.

Небольшие функции не только облегчают тестирование и отладку – само существование таких функций выполняет роль хороших комментариев!

Например, сравним ниже две функции showPrimes(n) . Каждая из них выводит простое число до n .

Первый вариант использует метку nextPrime :

Второй вариант использует дополнительную функцию isPrime(n) для проверки на простое:

Второй вариант легче для понимания, не правда ли? Вместо куска кода мы видим название действия ( isPrime ). Иногда разработчики называют такой код самодокументируемым.

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

Итого

Объявление функции имеет вид:

  • Передаваемые значения копируются в параметры функции и становятся локальными переменными.
  • Функции имеют доступ к внешним переменным. Но это работает только изнутри наружу. Код вне функции не имеет доступа к её локальным переменным.
  • Функция может возвращать значение. Если этого не происходит, тогда результат равен undefined .

Для того, чтобы сделать код более чистым и понятным, рекомендуется использовать локальные переменные и параметры функций, не пользоваться внешними переменными.

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

  • Имя функции должно понятно и чётко отражать, что она делает. Увидев её вызов в коде, вы должны тут же понимать, что она делает, и что возвращает.
  • Функция – это действие, поэтому её имя обычно является глаголом.
  • Есть много общепринятых префиксов, таких как: create… , show… , get… , check… и т.д. Пользуйтесь ими как подсказками, поясняющими, что делает функция.

Функции являются основными строительными блоками скриптов. Мы рассмотрели лишь основы функций в JavaScript, но уже сейчас можем создавать и использовать их. Это только начало пути. Мы будем неоднократно возвращаться к функциям и изучать их всё более и более глубоко.

Задачи

Обязателен ли "else"?

Следующая функция возвращает true , если параметр age больше 18 .

В ином случае она запрашивает подтверждение через confirm и возвращает его результат:

Будет ли эта функция работать как-то иначе, если убрать else ?

Есть ли хоть одно отличие в поведении этого варианта?

Оба варианта функций работают одинаково, отличий нет.

Перепишите функцию, используя оператор ‘?’ или ‘||’

Следующая функция возвращает true , если параметр age больше 18 .

В ином случае она задаёт вопрос confirm и возвращает его результат.

Перепишите функцию, чтобы она делала то же самое, но без if , в одну строку.

 

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

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