11 Функции. Определение. Имя функции. Независимость. Возвращаемое значение. Прототип. Синтаксис прототипа функции. Оператор return.
Функцией называется независимый фрагмент кода, имеющий собственное имя, предназначенный для выполнения определённой задачи и возвращающий значений в вызывающую программу (последнее не обязательно).
Имя функции. У каждой функции есть имя. Используя это имя в другой части программы выполняются операторы, содержащиеся в функции (это называется вызовом функции). Любую функцию можно вызывать из другой функции (кроме main).
Независимость. Функция выполняет свою задачу без вмешательства других функций.
Возвращаемое значение позволяет передать определённую информацию в вызывающую программу:
#include <iostream.h>
double cub(double x); // прототип функции
double cub(double x)
Прототип функции необходим , чтобы при компиляции вызовам функции был поставлен в соответствие формат её определения. Он состоит из спецификатора памяти (определённый тип возвращаемого значения), имени функции, стека передаваемых в неё параметров. Имена параметров указывать не обязательно, достаточно перечислить их типы.
Синтаксис прототипа функции:
тип_возвращаемого_значения
имя_функции(тип_аргумента1, тип_аргумента2. );
(наличие имён аргументов необязательно)
Int func(int, double, int); // описание прототипа функции
Сама функция и её полный текст называется определением функции.
Если прототип содержит имена аргументов, тогда первая строка определения (заголовок функции) должен полностью совпадать с прототипом (за исключением “;” после прототипа). Кроме того, в отличие от прототипа, имена аргументов в определении функции необходимы.
При определении функции после заголовка открывается операторная скобка.
Тело фукции — все её выполняемые операторы описывают метод, реализуемый данной функцией.
Возвращаемое значение передаётся оператором return, за которым следует выражение, определяющее это возвращаемое значение. Когда программа подходит к оператору return, вычисляется выражение, стоящие за ним, и его значение передаётся в вызывающую программу с одновременной передачей управления в неё. Функция может содержать несколько операторов return.
Можно объявить функцию, не возвращающую никакого значения, задавая пустой тип void.
Пример:
< . >// функция ничего не возвращает
12 Структурное программирование. Преимущества структурного программирования. Обработка вызова функции.
При таком подходе задача разбивается на отдельные подзадачи, каждая из которых выполняется независимыми фрагментами кода
Преимущества структурного программирования
1)Структурную программу легче понимать, т.к. сложная задача разбивается на много мелких простых. Каждая задача выполняется функцией, в которой и код, и переменные изолированы от остальной части программы.
2)Структурную программу легче отлаживать. Структурированность локализует ошибки.
При обработке вызова функции компилятор вставляет в код программы последовательность машинных команд, выполняющих следующие действия:
Выделение в стеке ячеек памяти, в которые записываются копии значений фактических параметров, адрес возврата и другие локальные переменные.
Если фактические параметры являются выражениями, то эти выражения будут вычислены и при необходимости приведены к соответствующему виду.
int f(int, float)
x = f(a+2, b+a); // параметры будут вычислены
// и в функцию будут переданы их значения
x = f(1, 2); // 2 будет приведено к типу float
f(i, ++i) // f(0,1) или f(1,1)?
В C принят такой порядок передачи аргументов, при котором первым вычисляется и передаётся последний в списке фактический параметр.
Т.к. порядок вычисления выражений фактических аргументов играет существенную роль, во избежание ошибок лучше вначале вычислять эти выражения, а затем подставлять в вызов функции.
Функции в 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 в результате своего выполнения всегда возвращает результат, даже если он явно не определён с помощью оператора return . Этот результат значение undefined .

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

«В компьютерном программировании соглашение об именах — набор правил для выбора последовательности символов, которая будет использоваться для идентификаторов, которые обозначают переменные, типы, функции и другие объекты в исходном коде и документации», — «Википедия»
Придумывать названия сложно!
В этой статье мы сосредоточимся на методе именования (P)A/HC/LC для того, чтобы улучшить читаемость кода. Эти рекомендации можно применить к любому языку программирования, в статье для примеров кода используется JavaScript.
Что значит (P)A/HC/LC?
В этой практике используется следующий шаблон для именования функции:
Что обозначает префикс (P)?
Префикс расширяет смысл функции.
Описывает свойство или состояние текущего контекста (обычно — логическое значение).
Указывает, имеет ли текущий контекст определенное значение или состояние (обычно — логическое значение).
Отражает положительный условный оператор (обычно — логическое значение), связанный с определенным действием.
Действие — это сердце функции
Действие — это глагольная часть имени функции. Это самая важная часть в описании того, что делает функция.
Получает доступ к данным немедленно (сокращение от getter для внутренних данных).
Безусловно присваивает переменной со значением A значение B.
Возвращает переменную к её начальному значению или состоянию.
Выполняет запрос данных, для которого требуется время (например, асинхронный запрос).
Удаляет что-то откуда-то.
Например, если у вас есть коллекция выбранных фильтров на странице поиска, удаление одного из них из коллекции — это removeFilter , а не deleteFilter (именно так вы и скажете на английском языке):
Полностью стирает что-то. После операции сущность перестаёт существовать.
Представьте, что вы редактор контента, и есть пост, от которого вы хотите избавиться. Как только вы нажали на кнопку delete-post, CMS выполнила действие deletePost , а не removePost .
Создает новые данные из существующих. Обычно это применимо к строкам, объектам или функциям.
Обработка действия. Часто используется при именовании обратного вызова.
Контекст
Контекст — это область, с которой работает функция.
Функция — это часто действие с чем-то. Важно указать, какова её рабочая область или, по крайней мере, ожидаемый тип данных.
В итоге

Пять принципов именования переменных
В этом разделе мы предложим некоторые правила именования переменных, которые улучшат читаемость кода.
1. Следуйте S-I-D
Имя должно быть коротким (Short), интуитивно понятным (Intuitive) и описательным (Descriptive).
2. Избегайте сокращений
Не используйте сокращения. Обычно они только ухудшают читаемость кода. Найти короткое, описательное имя может быть сложно, но сокращения не могут быть оправданием для того, чтобы этого не делать. Например:
3. Избегайте дублирования контекста
Всегда удаляйте контекст из имени, если это не снижает его читабельность.
4. Отражайте в имени ожидаемый результат
5. Учитывайте единственное/множественное число
Как и префикс, имена переменных могут быть единственного или множественного числа в зависимости от того, имеют ли они одно значение или несколько.
Имена методов и функций
Изучая всякого рода системы, я обнаружил, что у многих наблюдаются проблемы с именованием методов. Это побудило меня написать статью.
Что побудило меня написать статью?
После того, как я в тысячный раз полез в мануал, чтобы узнать порядок аргументов в PHP-функции str_replace, стало ясно, что проблема весьма актуальна. Ведь имя функции «str_replace» говорит нам только о том, что она делает, но ничего не говорит об аргументах. Чем это чревато? Ладно, можно запомнить число и порядок аргументов во встроенной библиотеке, но в собственной разработке запоминать аргументы не так-то и просто. Да, есть среды разработки, которые нам подсказывают, но они не срабатывают при наведении глаза на функцию, поэтому читать такой код сложно. А ведь важно, чтобы код легко читался и понимался без комментариев. Это признак качественного кода.
В качестве примера многочисленных ошибок, приведу PHP. Сразу могу назвать несколько ошибок:
1. Имена некоторых функций неочевидно передают назначение. Например, basename.
2. Имена функций составлены не по одному принципу. Например, строковые функции начинаются с str_, но не все (например, strstr, strpos). С файлами та же проблема: filesize vs file_exists.
3. Неочевидность аргументов и их порядка в функциях. Например, искомая строка в функции str_replace идет на последнем месте, а в функции strpos — на первом (str_replace($search, $replace, $subject[, $&count]) vs strpos($haystack, $needle[, $offset])). Если бы искомая строка, например, всегда занимала первую позицию — было бы более удобно.
Да, таково наследство Си (и не только), но неважно: проблема есть проблема.
Значит, надо придумывать имена методов/функций так, чтобы:
1. Имя функции/метода четко передавало его назначение.
2. Имена функций/методов составлены по одному принципу/стандарту.
3. Порядок и список аргументов в функциях/методах были составлены по одному принципу и сочетались с именем.
4. Методы оставались методами.
Поясню 4ый пункт. Нередко я встречаю строки вида object.Pi(): такой метод не имеет отношения к объекту. Это скорее функция (или константа).
Примеры и не только
1. Нам нужна замена подстроки в строке. Самым очевидным вариантом будет такой: string.replace(from, to). Жаль, что в PHP он не осуществим.
2. Намекаем на аргументы и смысл: groups.getByName(name). Ничего лишнего. Не надо писать getGroupByName, ведь контекст ясен благодаря groups. Точно так же и другие методы: groups.remove(group) либо group.delete(). Ага! И тут интересный момент 🙂 Если мы удаляем из коллекции, то коллекция.remove(элемент). А если элемент сам удаляет себя, то элемент.delete(). И это важно: наш код должен быть валидным в плане английского языка.
3. Антонимы в именах функций/методов. Да, всегда надо использовать верные антонимы при именовании. Добавляем и удаляем элементы в коллекции: add/remove. Создаем и удаляем объекты: create/delete. Начинаем и завершаем процесс: begin/end, start/finish (но никак не begin/finish и start/end).