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

Функция (function) – это самостоятельный фрагмент кода, решающий определенную задачу. Каждой функции присваивается уникальное имя, по которому ее можно идентифицировать и «вызвать» в нужный момент.

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

В JavaScript есть встроенные функции, которые можно использовать в программах, но код которых нельзя редактировать или посмотреть. Примеры встроенных функций вы уже видели – это alert(), prompt(), confirm() и document.write(). Кроме использования встроенных функций, вы можете создать свои собственные, так называемые пользовательские функции.

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

Функция JavaScript определяется с помощью ключевого слова function, за которым указываются следующие компоненты:

  • Идентификатор, определяющий имя функции. Чаще всего в качестве имен функций выбираются глаголы или фразы, начинающиеся с глаголов. По общепринятому соглашению имена функций начинаются со строчной буквы.
  • Пара круглых скобок (), которые могут включать имена параметров, разделенных запятыми ( параметр1, параметр2, ... ). Эти имена параметров в теле функции могут использоваться как локальные переменные.
  • Пара фигурных скобок {} с инструкциями JavaScript внутри. Эти инструкции составляют тело функции: они выполняются при каждом вызове функции.

Синтаксис функции JavaScript:

function идентификатор(параметры) {
  инструкции
}

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

Выполнить код »

Этот код выведет нам приветствие в диалоговом окне alert() два раза. Применение функции позволило нам избавиться от дублирования кода.

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

Интерпретатор JavaScript, встречая ключевое слово function, создаёт функцию и переменную с именем этой функции. Переменной присваивается ссылка на функцию.

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

alert(sayHello);   // function sayHello() { alert("Привет!"); }

Ссылку на функцию вы можете сохранить в любой переменной, например:

var fun = sayHello; //  Имя функции указываем без скобок 
fun(); // Вызываем функцию sayHello() по ссылке 

«Классическое» объявление функции function имя(параметры) {код} называется в спецификации языка «Function Declaration».

Существует альтернативный синтаксис для объявления функции «Function Expression» (функциональное выражение) – это объявление функции, которое является частью какого-либо выражения (например присваивания):

var sayHello = function () {
  alert("Привет!");
};
//вызов функции
sayHello();

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

Если у функции нет имени, как в предыдущем примере, она называется «анонимной».

Разница между представленными объявлениями заключается в том, что функции, объявленные как «Function Declaration», создаются интерпретатором до начала выполнения кода (на этапе анализа), поэтому их можно вызвать до объявления:

// Вызов функции до её объявления
sayHello("John"); // Привет, John

function sayHello(name) {
  alert( "Привет, " + name );
}

Функции «Function Expression» (функциональные выражения) создаются в процессе выполнения выражения, в следующем примере функция будет создана при операции присваивания sayHi = function..., поэтому вызов функции до её объявления приведёт к ошибке:

// Вызов функции до её объявления
sayHello("John"); // ошибка!

var sayHello = function(name) {
  alert( "Привет, " + name );
}

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

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

function name_func(parameter1, parameter2, parameter3...) {
    тело функции
}

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

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

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

name_func(argument1, argument2, argument3...)

Например, при вызове функции sum ей передаются два аргумента:

Выполнить код »

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

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

  1. Если при вызове функции ей передаётся больше аргументов, чем задано параметров, то «лишние» аргументы просто игнорируются и не присваиваются ни одному из параметров данной функции.
  2. Если количество аргументов, передаваемых функции при её вызове меньше, чем было указано параметров при объявлении, то параметрам без соответствующих аргументов присваивается значение undefined. Подобное поведение JavaScript удобно использовать, если некоторые аргументы функции необязательны и могут опускаться.

Типы аргументов, передаваемых функции при её вызове, могут быть как примитивами (строки, числа, логические величины (boolean)), так и объектами (в т.ч. массивы и функции).

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

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

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

Выполнить код »

В этом примере мы видим, что внутри функции myFunc был изменен объект obj, и эти изменения повлияли на этот объект за пределами функции.

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

Инструкция return имеет следующий синтаксис:

return выражение;

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

Выполнить код »

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

Инструкция return может быть расположена в любом месте функции. После инструкции return происходит выход из функции. Все операторы, расположенные в коде по­сле инструкции return, не будут выполнены, например:

Выполнить код »

В инструкции return можно указать сразу выражение, перепишем нашу функцию sum:

Выполнить код »

Внутри функции можно использовать несколько инструкций return:

Выполнить код »

В случае, если в функции нет инструкции return или return указана без аргументов, то функция вернёт значение undefined:

Выполнить код »

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

Свойство length этого объекта содержит число переданных аргументов.

На­пишем функцию, вычисляющую сумму произвольного числа аргумен­тов:

Выполнить код »

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

Поскольку он похож на массив, обратиться к переданным функции аргументам можно так же, как и к элементам массива: первый аргумент будет доступен в теле функ­ции как элемент массива arguments[0],

второй аргумент

будет доступен как элементarguments[1] и т.д.

Функция, приводимая в следующем примере, возвращает строку, содержащую значения параметров (переданные аргументы) и их общее количество, которые были указаны в вызове функции (не в ее определении):

Выполнить код »

Интерпретатор JavaScript всегда перемещает («поднимает») объявления функций и переменных в начало области видимости. Если переменная определена внутри функции, она поднимается к верхней части функции, а если переменная определена глобально — к верхней части глобального контекста. Рассмотрим, что это значит на примере:

var name = "John";

function showName() {
    alert( "First Name: " + name );
    var name = "Stiv";
    alert( "Last Name: " + name );
}
showName(); 

// First Name: undefined
// Last Name: Stiv

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

В случае с функциями, поднимается вся функция целиком, если речь идет о функциях-объявлениях (declaration); функция-выражение (expression) не поднимается:

function testFunc() { 
    myFunc(); // "Эта инструкция сработает!"
    anomFunc(); // Uncaught TypeError: anomFunc is not a function     
    var anomFunc = function() { // функциональное выражение «Function Expression»
        alert( "Эта инструкция не сработает!" ); 
    } 
    function myFunc() { // объявление функции «Function Declaration» 
        alert( "Эта инструкция сработает!" ); 
    } 
} 
testFunc();

В этом этом примере поднимается только функция myFunc. Идентификатор «anomFunc» (переменная, которой присвоена функция) также поднимается, но сама анонимная функция при этом остаётся на месте (как и в случае с пременной).

  • «Классическое» объявление функции («Function Declaration») обрабатывается рань­ше остального кода. Такую функцию можно вызвать до её объявления.
  • Функциональные выражения («Function Expression») обрабатыва­ются вместе с остальным кодом. Такую функцию нельзя вызвать до её объявления.
  • Функции в JavaScript являются значениями. Их можно присваивать, передавать, создавать в любом месте кода. В отличие от других видов значений функцию можно вызвать для выполнения кода, содержащегося в ее теле.
  • Процесс вызова функции, созданной по объ­явлению («Function Declaration»), не отличается от процесса вызова функции, созданной по выражению («Function Expression»).
  • Ссылки на функции могут храниться в пе­ременных.
  • Передаваемые при вызове функции аргументы копируются в параметры функции и становятся локальными переменными.
  • Функция может возврвщать значение с помощью инструкции return (значение).
  • После инструкции return происходит выход из функции.
  • Если оператор return вызван без значения, или в теле функции не указан return, то её результат равен undefined.
  • Функция представляет из себя определённое действие, поэтому в качестве имен функций выбираются глаголы или фразы, начинающиеся с глаголов.

  • Максимальное число

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

    Показать решение

    Решение:

    Выполнить код »
  • Сравнение двух чисел

    Написать функцию, которая запрашивает у пользователя два целых числа и возвращает результат их сравнения в виде одного из знаков: >, < или =..

    Показать решение

    Решение:

    Выполнить код »
  • Строка из звёэдочек

    Напишите функцию, которая выводит на экран строку, состоящую из звездочек *. Длина строки (количество звездочек) является параметром функции. Пусть функция нарисует строку из десяти звёздочек.

    Показать решение

    Решение:

    Выполнить код »
  • Вывести на экран все натуральные числа до заданного

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

    0 1 2 3 4 5 6 7 8 9 10 11
    
    Показать решение

    Решение:

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

    Выполнить код »
  • Перепишите функцию, используя оператор '?'

    Следующая функция возвращает "Привет мир!", если параметр speech == ru. В ином случае она возвращает "Hello world!". Перепишите функцию, чтобы она делала то же самое, но без if, используя оператор '?'.

    function getGreeting(speech) {
      if (speech == ru) {
        return "Привет мир!";
      } else {
        return "Hello world!";
      }
    }
    
    Показать решение

    Решение:

    Выполнить код »

Комментарии

пожелания к комментариям…
  • Приветствуются комментарии, соответствующие теме урока: вопросы, ответы, предложения.
  • Одну строчку кода оборачивайте в тег <code>, несколько строчек кода — в теги <pre><code>...ваш код...</code></pre>.
  • Допускаются ссылки на онлайн-песочницы (codepen, plnkr, JSBin и др.).