что такое параметры функции
2.3 – Введение в параметры и аргументы функций
Однако что, если мы также захотим поместить строку вывода в отдельную функцию? Вы можете попробовать что-то вроде этого:
Хотя это устраняет ошибку компиляции и делает программу пригодной для компиляции, программа по-прежнему работает некорректно (всегда выводит « 0 doubled is: 0 »). Суть проблемы здесь в том, что у функции printDouble нет способа получить доступ к значению, введенному пользователем.
Параметры и аргументы функции
Во многих случаях полезно иметь возможность передавать информацию вызываемой функции, чтобы у этой функции были данные для работы. Например, если мы хотим написать функцию для сложения двух чисел, нам нужен способ сообщить этой функции, какие два числа нужно складывать при ее вызове. Иначе как функция узнает, что складывать? Мы делаем это с помощью параметров и аргументов функции.
Параметр функции – это переменная, используемая в функции. Параметры функции работают почти так же, как переменные, определенные внутри функции, но с одним отличием: они всегда инициализируются значением, предоставленным вызывающей функцией.
Параметры функции определяются в объявлении функции путем помещения их в скобки после идентификатора функции, при этом несколько параметров разделяются запятыми.
Вот несколько примеров функций с разным количеством параметров:
Аргумент – это значение, которое передается от вызывающей стороны к функции при ее вызове:
Обратите внимание, что несколько аргументов также разделяются запятыми.
Как параметры и аргументы работают вместе
Когда функция вызывается, все параметры функции создаются как переменные, а значение каждого из аргументов копируется в соответствующий параметр. Этот процесс называется передачей по значению.
Когда функция printValues вызывается с аргументами 6 и 7, параметр x в printValues создается и инициализируется значением 6, а параметр y в printValues создается и инициализируется значением 7.
Это дает в результате следующий вывод:
Обратите внимание, что количество аргументов обычно должно соответствовать количеству параметров функции, иначе компилятор выдаст ошибку. Аргумент, переданный функции, может быть любым допустимым выражением (поскольку аргумент является, по сути, просто инициализатором для параметра, а инициализатор может быть любым допустимым выражением).
Исправляем нашу тестовую программу
Теперь у нас есть инструмент, необходимый для исправления программы, представленной в начале урока:
Использование возвращаемых значений в качестве аргументов
Мы можем немного упростить приведенный выше пример следующим образом:
Хотя эта программа более лаконична (и дает понять, что значение, прочитанное пользователем, не будет использоваться ни для чего другого), вы также можете решить, что этот «компактный синтаксис» немного труднее для чтения. Если вам удобнее придерживаться версии, в которой вместо этого используется переменная, ничего страшного.
Предупреждение о порядке вычисления аргументов функции
Спецификация C++ не определяет, сопоставляются ли аргументы с параметрами в порядке слева направо или справа налево. При копировании значений порядок не имеет значения. Однако если аргументы являются вызовами функций, это может быть проблематично:
Если важно, чтобы какой-либо аргумент вычислялся первым, вы должны явно определить порядок выполнения, например:
Предупреждение
Спецификация C++ не определяет, будут ли вызовы функций вычислять аргументы слева направо или справа налево. Позаботьтесь о том, чтобы не использовать функции в качестве аргументов, где порядок их вызовов имеет значение.
Как параметры и возвращаемые значения работают вместе
Используя оба параметра и возвращаемое значение, мы можем создавать функции, которые принимают входные данные, выполняют с ними какие-либо вычисления и возвращают значение вызывающей стороне.
Вот пример очень простой функции, которая складывает два числа и возвращает результат вызывающей функции:
В графическом виде это выглядит так:
Рисунок 1 – Передача функции аргументов и возврат рассчитанного ею значения
Еще примеры
Давайте взглянем еще на несколько вызовов функций:
Эта программа создает в консоли следующий вывод:
Первая инструкция простая.
Следующая пара инструкций также относительно проста:
Давайте посмотрим на первую сложную инструкцию в этой связке:
Менее подробно: add(1, add(2, 3)) вычисляется как add(1, 5) => вычисляется как 6
Заключение
Параметры функций и возвращаемые значения являются ключевыми механизмами, с помощью которых функции могут быть написаны для повторного использования, поскольку это позволяет нам писать функции, которые могут выполнять задачи и возвращать извлеченные или вычисленные результаты обратно вызывающей стороне, не зная заранее конкретных входных и выходных данных.
Небольшой тест
Вопрос 1
Что не так с этим фрагментом программы?
Вопрос 2
Какие две вещи неправильны в этом фрагменте программы?
Вопрос 3
Какое значение выводит следующая программа?
Вопрос 4
Вопрос 5
Примечание: вы можете предложить другие (похожие) решения. В C++ часто есть много способов сделать одно и то же.
Функции в JavaScript. Классический способ создания
Статья, в которой рассмотрим, что такое функция и зачем она нужна. Разберём классический способ её объявления, параметры, аргументы и оператор return.
Что такое функция?
Функция – это именованный фрагмент кода, к которому можно обратиться в нужных местах программы по имени.
Довольно часто случается, что какие-то строчки кода повторяются. Чтобы уйти от этого можно написать функцию, а затем просто вызывать её в разных местах. Это один из классических сценариев использования функций, который позволяет упростить написание программ на JavaScript.
Кроме этого, функции позволяют очень хорошо структурировать код.
Например, если перед вами стоит какая-то задача, то чтобы проще её решить, можно разбить её на подзадачи, которые решают какие-то определённые функции. А затем уже используя их написать финальный код, который в данном случае сделать будет очень просто. Вдобавок к этому в такой код будет более просто вносить различные изменения и добавлять новые возможности.
JavaScript позволяет создавать функцию различными способами:
Объявление и вызов функции
Операции с функцией в JavaScript можно разделить на 2 этапа:
При составлении имени функции необходимо руководствоваться такими же правилами, что для переменной. Т.е. можно использовать буквы, цифры (0 – 9), знаки «$» и «_». В качестве букв рекомендуется использовать английский алфавит (a-z, A-Z). Имя функции, также как и имя переменной не может начинаться с цифры.
Параметры предназначены для получения значений, переданных в функцию, по имени. Их именование осуществляется также как переменных. Разделение параметров друг от друга осуществляется с помощью запятой.
Пример функции с двумя параметрами:
Если параметры не нужны, то круглые скобки в любом случае указываются.
Тело функции – это код, заключенный в фигурные скобки, который необходимо выполнить при её вызове.
2. Вызов функции. Объявленная функция сама по себе не выполняется. Для того чтобы функцию запустить, её необходимо вызвать. Вызов функции осуществляется посредством указания её имени и двух круглых скобок. Внутрь скобок при необходимости можно передать значения (аргументы) разделяя их между собой с помощью запятой.
Параметры и аргументы
Параметры – это переменные, которые описываются в круглых скобках на этапе объявления функции. Параметры доступны только внутри функции, получить доступ к ним снаружи нельзя.
Аргументы – это значения, которые передаём функции в момент её вызова.
Но если значение является ссылкой, то его изменения будет видно за пределами функции:
Переменные, объявленные внутри функции, называются локальными. Они не доступны вне функции.
При этом если переменная расположена вне всех функций, она называется глобальной.
arguments
Параметры – это не единственный способ, с помощью которого в JavaScript можно получить аргументы функции.
Доступ к аргументам через arguments выполняется точно также как к элементам обычного массива, т.е. по порядковому номеру.
Получение аргументов через arguments в основном используется, когда мы заранее не знаем их точное количество.
Например, создадим функцию, которые будет подсчитывать сумму всех аргументов, являющихся числами:
Через цикл for. of этот пример можно записать так:
При необходимости arguments можно преобразовать в обычный массив.
В JavaScript arguments можно использовать для написания очень гибких функций, которые в зависимости от количества аргументов, и, их типа, могут выполнять различные действия.
Все переменные, созданные внутри функции и её параметры являются локальными переменными этой функции. Они доступны только внутри этой функции, а также в других функциях, вложенных в неё, если там нет переменных с такими же именами. Вне функции её локальные переменные не доступны.
При этом внешняя переменная или функция будет доступна внутри неё.
Передачи одной функции в другую. Колбэки
Узнать является ли некоторый идентификатор функцией можно с помощью typeof :
Например, проверим является ли колбэк функцией перед тем как его вызвать:
Возвращаемое значение (return)
Без использования return :
С использованием return :
Инструкции, расположенные после return никогда не выполняются:
Функция, которая возвращает функцию
В качестве результата функции мы можем также возвращать функцию.
При создании таких конструкций нет ограничений по уровню вложенности, но с точки зрения разумности этим лучше не злоупотреблять.
Функцию, приведённую в коде мы можем также создать и так:
Кроме этого в качестве результата мы можем также возвратить внешнюю функцию:
Рекурсия
Функцию можно также вызвать внутри самой себя. Это действие в программировании называется рекурсией.
Кроме этого необходимо предусмотреть условия для выхода из рекурсии. Если это не сделать функция будет вызывать сама себя до тех пор, пока не будет брошена ошибка, связанная с переполнением стека.
Например, использование рекурсии для вычисления факториала числа:
Пример, в котором используя рекурсию выведем числа от указанного до 10:
Перегрузка функций в JavaScript
Перегрузка функций в программировании – это возможность объявлять в одном месте несколько функций с одинаковыми именами. Отличаются такие функции друг от друга параметрами. Используется перегрузка функций для того, чтобы можно было вызвать подходящую под переданные аргументы функцию.
В JavaScript не реализована перегрузка функций в том виде, как это реализовано в Си или других языках. Но подобную функциональность можно имитировать в JavaScript. Для этого у нас есть всё, что для этого необходимо.
Пример реализации «перегруженной» функции для вычисления оптимального количества ккал, которых необходимо человеку в день:
Новые возможности, которые появились в ES6+ для функций
Значение параметра по умолчанию
В языке, начиная с версии ECMAScript 6+ (2015+) параметру функции можно задать значение по умолчанию.
Например, установим параметру color значение по умолчанию ‘#009688’ :
До появление такой возможности в языке, задание параметру значения по умолчанию выполнялось так:
Оставшиеся параметры (rest parameters)
Что такое встроенные (стандартные) функции
В JavaScript имеется огромный набор встроенных (стандартных) функций. Данные функции уже описаны в самом движке браузера. Практически все они являются методами того или иного объекта.
Например, для того чтобы вызвать встроенную функцию (метод) alert, её не надо предварительно объявлять. Она уже описана в браузере. Вызов метода alert осуществляется посредством указания имени, круглых скобок и аргумента внутри них. Данный метод предназначен для вывода сообщения на экран в форме диалогового окна. Текстовое сообщение берётся из значения параметра данной функции.
Такой же результат будет получен, если для оператора return не указать возвращаемое значение.
JavaScript Параметры функции
JavaScript function не выполняет никаких проверок значений параметров (аргументов).
Параметры и аргументы функции
Ранее в этом руководстве вы узнали, что функции могут иметь параметры:
Правила параметра
В определениях функций JavaScript не указываются типы данных для параметров.
Функции JavaScript не выполняют проверку типов переданных аргументов.
Функции JavaScript не проверяют количество полученных аргументов.
Параметры по умолчанию
Иногда это приемлемо, но иногда лучше присвоить параметру значение по умолчанию:
Пример
ECMAScript 2015 допускает значения параметров по умолчанию в объявлении функции:
Объект аргументов
Функции JavaScript имеют встроенный объект, называемый объектом аргументов.
Объект аргумента содержит массив аргументов, используемых при вызове (вызове) функции.
Таким образом, вы можете просто использовать функцию для поиска (например) наивысшего значения в списке чисел:
Пример
x = findMax(1, 123, 500, 115, 44, 88);
Или создайте функцию для суммирования всех входных значений:
Пример
x = sumAll(1, 123, 500, 115, 44, 88);
function sumAll() <
var i;
var sum = 0;
for (i = 0; i
Аргументы передаются по значению
Параметры в вызове функции являются аргументами функции.
Аргументы JavaScript передаются по значению: функция узнает только значения, но не расположение аргументов.
Если функция изменяет значение аргумента, она не меняет исходное значение параметра.
Изменения аргументов не видны (не отражаются) вне функции.
Объекты передаются по ссылке
В JavaScript ссылки на объекты являются значениями.
Из-за этого объекты будут вести себя так, как будто они переданы по ссылке:
Если функция изменяет свойство объекта, она изменяет исходное значение.
Изменения свойств объекта видны (отражаются) вне функции.
Руководство по JavaScript, часть 4: функции
Сегодня публикуем четвёртую часть перевода руководства по JavaScript, которая посвящена функциям.
Функции в JavaScript
Поговорим о функциях в JavaScript, сделаем их общий обзор и рассмотрим подробности о них, знание которых позволит вам эффективно ими пользоваться.
Функция — это самостоятельный блок кода, который можно, один раз объявив, вызывать столько раз, сколько нужно. Функция может, хотя это и необязательно, принимать параметры. Функции возвращают единственное значение.
Кроме того, функции в JavaScript называют «функциями первого класса» так как их можно назначать переменным, их можно передавать другим функциям в качестве аргументов, их можно возвращать из других функций.
Сначала рассмотрим особенности работы с функциями и соответствующие синтаксические конструкции, которые существовали в языке до появления стандарта ES6 и актуальны до сих пор.
Вот как выглядит объявление функции (function declaration).
В наши дни такие функции называют «обычными», отличая их от «стрелочных» функций, которые появились в ES6.
Функцию можно назначить переменной или константе. Такая конструкция называется функциональным выражением (function expression).
Можно заметить, что в вышеприведённом примере функция назначена константе, но сама она имени не имеет. Такие функции называют анонимными. Подобным функциям можно назначать имена. В таком случае речь идёт об именованном функциональном выражении (named function expression).
Использование таких выражений повышает удобство отладки (в сообщениях об ошибках, где проводится трассировка стека, видно имя функции). Имя функции в функциональном выражении может понадобиться и для того, чтобы функция могла бы сама себя вызывать, без чего не обойтись при реализации рекурсивных алгоритмов.
В стандарте ES6 появились стрелочные функции (arrow function), которые особенно удобно использовать в виде так называемых «встроенных функций» (inline function) — в роли аргументов, передаваемых другим функциям (коллбэков).
Стрелочные функции, помимо того, что структуры, используемые для их объявления, получаются более компактными, чем при использовании обычных функций, отличаются от них некоторыми важными особенностями, о которых мы поговорим ниже.
Параметры функций
Параметры представляют собой переменные, которые задаются на этапе объявления функции и будут содержать передаваемые ей значения (эти значения называют аргументами). Функции в JavaScript могут либо не иметь параметров, либо иметь один или несколько параметров.
Здесь показано несколько примеров стрелочных функций.
Начиная со стандарта ES6 у функций могут быть так называемые «параметры по умолчанию» (default parameters).
Они представляют собой стандартные значения, задаваемые параметрам функций в том случае, если при её вызове значения некоторых параметров не задаются. Например, функцию, показанную выше, можно вызвать как с передачей ей всех двух принимаемых ей параметров, так и другими способами.
В ES8 появилась возможность ставить запятую после последнего аргумента функции (это называется trailing comma). Эта возможность позволяет повысить удобство редактирования кода при использовании систем контроля версий в ходе разработки программ. Подробности об этом можно почитать здесь и здесь.
Передаваемые функциям аргументы можно представлять в виде массивов. Для того чтобы разобрать эти аргументы можно воспользоваться оператором, который выглядит как три точки (это — так называемый «оператор расширения» или «оператор spread»). Вот как это выглядит.
Если функции нужно принимать много параметров, то запомнить порядок их следования может быть непросто. В таких случаях используются объекты с параметрами и возможности по деструктурированию объектов ES6.
Этот приём позволяет, описывая параметры в виде свойств объекта и передавая функции объект, получить в функции доступ к параметрам по их именам без использования дополнительных конструкций. Подробнее об этом приёме можно почитать здесь.
Значения, возвращаемые из функций
Если после ключевого слова return указать некое значение, то это значение возвращается в место вызова функции в качестве результата выполнения этой функции.
Из функции можно возвращать лишь одно значение. Для того чтобы получить возможность возврата нескольких значений, возвращать их можно либо в виде объекта, используя объектный литерал, либо в виде массива, а при вызове функции применять конструкцию деструктурирующего присваивания. Имена параметров при этом сохраняются. При этом, если нужно работать с объектом или массивом, возвращённым из функции, именно в виде объекта или массива, можно обойтись без деструктурирующего присваивания.
Конструкцию const [ name, age ] = doSomething() можно прочитать следующим образом: «объявить константы name и age и присвоить им значения элементов массива, который возвратит функция».
Вот как то же самое выглядит с использованием объекта.
Вложенные функции
Функции можно объявлять внутри других функций.
Область видимости вложенной функции ограничена внешней по отношению к ней функцией, её нельзя вызвать извне.
Методы объектов
Когда функции используются в качестве свойств объектов, такие функции называют методами объектов.
Ключевое слово this
Как видно, вызов метода start() приводит ко вполне ожидаемому результату, а вот метод stop() явно работает неправильно.
Вот как выглядит выполнение такого кода в консоли браузера.
Особенности ключевого слова this в обычных и стрелочных функциях
Всё это означает, что стрелочные функции не подходят на роль методов объектов и конструкторов (если попытаться использовать стрелочную функцию в роли конструктора — будет выдана ошибка TypeError ).
Немедленно вызываемые функциональные выражения
Немедленно вызываемое функциональное выражение (Immediately Invoked Function Expression, IIFE) — это функция, которая автоматически вызывается сразу после её объявления.
Точка с запятой перед IIFE необязательна, но её использование позволяет застраховаться от ошибок, связанных с автоматической расстановкой точек с запятой.
Поднятие функций
Если переместить вызов функции так, чтобы он шёл после её объявления, ничего не изменится.
Если же в похожей ситуации воспользоваться функциональным выражением, то похожий код выдаст ошибку.
Стрелочные функции
Сейчас мы подробнее поговорим о стрелочных функциях, с которыми мы уже встречались. Их можно считать одним из наиболее значительных новшеств стандарта ES6, они отличаются от обычных функций не только внешним видом, но и особенностями поведения. В наши дни они используются чрезвычайно широко. Пожалуй, нет ни одного современного проекта, где они не использовались бы в подавляющем большинстве случаев. Можно сказать, что их появление навсегда изменило и внешний вид JS-кода и особенности его работы.
С чисто внешней точки зрения синтаксис объявления стрелочных функций оказывается компактнее синтаксиса обычных функций. Вот объявление обычной функции.
Вот объявление стрелочной функции, которое, в целом, если не учитывать особенности стрелочных функций, аналогично предыдущему.
Как видите, параметры стрелочных функций, как и в случае с обычными функциями, описывают в скобках. При этом, если такая функция принимает всего один параметр, его можно указать без скобок. Например, вот функция, которая возвращает результат деления переданного ей числа на 2.
В результате оказывается, что стрелочные функции очень удобно использовать в ситуациях, в которых нужны маленькие функции.
▍Неявный возврат результатов работы функции
Мы уже касались этой особенности стрелочных функций, но она настолько важна, что её следует обсудить подробнее. Речь идёт о том, что однострочные стрелочные функции поддерживают неявный возврат результатов своей работы. Пример возврата примитивного значения из однострочной стрелочной функции мы уже видели. Как быть, если такая функция должна возвратить объект? В таком случае фигурные скобки объектного литерала могут запутать систему, поэтому в теле функции используются круглые скобки.
▍Ключевое слово this и стрелочные функции
Как мы уже видели, при использовании ключевого слова this в методе объекта, представленного обычной функцией, this указывает на объект, которому принадлежит метод. В таком случае говорят о привязке ключевого слова this к значению, представляющему собой контекст выполнения функции. В частности, если функция вызвана в виде метода объекта, то ключевое слово this привязано к этому объекту.
В случае же со стрелочными функциями оказывается так, что в них привязка this не выполняется, они пользуются ключевым словом this из содержащих их областей видимости. В результате их не рекомендуется использовать в качестве методов объектов.
Замыкания
Замыкания — это важная концепция в JavaScript. Фактически, если вы писали JS-функции, то вы пользовались и замыканиями. Замыкания применяются в некоторых паттернах проектирования — в том случае, если нужно организовать строгий контроль доступа к неким данным или функциям.
Когда функция вызывается, у неё есть доступ ко всему тому, что находится во внешней по отношению к ней области видимости. Но к тому, что объявлено внутри функции, извне доступа нет. То есть, если в функции была объявлена некая переменная (или другая функция), они недоступны внешнему коду ни во время выполнения функции, ни после завершения её работы. Однако если из функции возвратить другую функцию, то эта новая функция будет иметь доступ ко всему тому, что было объявлено в исходной функции. При этом всё это будет скрыто от внешнего кода в замыкании.
Рассмотрим пример. Вот функция, которая принимает имя собаки, после чего выводит его в консоль.
Значение, возвращаемое этой функцией нас пока не интересует, текст выводится в консоль с помощью IIFE, что в данном случае особой роли не играет, однако, это поможет нам увидеть связь между этой функцией и её вариантом, в котором, вместо вызова функции, которая выводит текст в консоль, мы эту функцию из переписанной функции bark() возвратим.
Результат работы код в двух случаях оказывается одинаковым. Но во втором случае то, что было передано исходной функции при её вызове (имя собаки, Roger ), хранится в замыкании, после чего используется другой функцией, возвращённой из исходной.
Проведём ещё один эксперимент — создадим, пользуясь исходной функцией, две новых, для разных собак.
Этот код выведет следующее.
Итоги
Уважаемые читатели! Как вы относитесь к стрелочным функциям в JavaScript?