Home

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

Содержание

1. Вступление

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

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

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

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

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

example img

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

Дональд Кнут

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

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

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

Пример

'use strict';
function print(str, n) {
    var newStr = '';
    for (var i = 0; i < n; i++ ) {
        newStr += str;
    }
    console.log(newStr);
}

Пример

'use strict';
function square(x) {
    console.log(x*x);
}

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

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

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

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

Пример

'use strict';
square(1+1); // 4
print('+', 5); // '+++++';

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

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

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

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

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

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

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

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

Пример

'use strict';
function showMessage(from, text) {
    if (text === undefined) {
        text = 'текст не передан';
    }
    alert( from + ": " + text );
}
showMessage("Маша", "Привет!"); // Маша: Привет!
showMessage("Маша"); // Маша: текст не передан

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

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

Пример

'use strict';
function lbsToKg (pounds) {
    return 0.453592 * pounds;
}
var lbs = prompt('Введите вес в фунтах: ', '');
var kgs = lbsToKg(lbs);
console.log('Вес в килограммах равен ', kgs);

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

Пример

'use strict';
function showMovie(age) {
    if (!checkAge(age)) {
        return;
    }
    alert( "Фильм не для всех" ); // (*)
    // ...
}

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

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

Пример

'use strict';
function square(x) {
    return x*x;
}
var result = square(2);
console.log(result);

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

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

Пример

'use strict';
function showMessage() {
    var message = 'Привет, я - Вася!'; // локальная переменная
    alert( message );
}
showMessage(); // 'Привет, я - Вася!'
alert( message ); // будет ошибка, т.к. переменная видна только внутри

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

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

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

Пример

'use strict';
var userName = 'Вася';
function showMessage() {
    var message = 'Привет, я ' + userName;
    alert(message);
}
showMessage(); // Привет, я Вася

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

Пример

'use strict';
var userName = 'Вася';
function showMessage() {
    userName = 'Петя'; // (1) присвоение во внешнюю переменную
    var message = 'Привет, я ' + userName;
    alert( message );
}
showMessage();
alert( userName ); // Петя, значение внешней переменной изменено функцией

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

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

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

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

Пример

'use strict';
function getValue(condition) {
    if (condition) {
        var value = "blue";
        // другой код
        return value;
    } else {
        // здесь переменная value будет существовать со значением undefined
        return null;
    }
    // здесь переменная value будет существовать со значением undefined
}

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

Пример

'use strict';
function getValue(condition) {
    var value;
    if (condition) {
        value = "blue";
        // другой код тут
        return value;
    } else {
        return null;
    }
}

Переменная 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).