Как использовать функции в JavaScript?

Функции в JavaScript: учимся писать структурированные программы

Александр Дудукало
Александр Дудукало Автор одноименного YouTube-канала
22 ноября 2024

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

Изображение записи

Привет! Я — Александр Дудукало, автор базового курса по JavaScript. Сегодня поговорим о функциях и возвращении значений из них. Научимся писать более структурированные программы, расскажем про ключевое слово return и области видимости в JavaScript.

Для создания кода подготовим проект по аналогии с тем, как это было сделано в моем предыдущем тексте «Как использовать типы данных в JavaScript? Переменные, ввод и вывод информации».

Скриншот проекта.

Области видимости

Для начала предлагаю познакомиться с областями видимости. Напишем простой код и запустим его в браузере через Live Server.

Как установить Live Server.

В прошлом тексте я делился небольшой инструкцией, как это сделать: переходим во вкладку Extensions, вводим название плагина в поиск, выбираем open live server → install. После установки нажимаем на index.html ПКМOpen with Live Server.

Скриншот всплывающего окна с кнопкой «Open with Live Server».

    let age = 18;
console.log(age);
let age = 18;

Видим, что переменная age подчеркнута красным цветом, а в консоли браузера — ошибка.

Скриншот: переменная age подчеркнута.
Переменная age подчеркнута.

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


    {
let age = 18;
console.log(age);
}

{
let age = 18;
}
Скриншот: переменные больше не подчеркиваются красным цветом.
Переменные больше не подчеркиваются красным цветом.
Скриншот: ошибка в браузере исчезла и сменилась результат программы.
Ошибка в браузере исчезла и сменилась результат программы.

Фигурные скобки — это блоки кода, которые создают области видимости. Но что же это такое? По сути, область видимости — это некая коробка, в которой хранятся значения. Согласитесь, чем-то напоминает переменные. При этом сами значения не взаимодействуют между собой и не знают друг о друге. 

Когда мы написали код, мы поместили его в глобальную область видимости, а сейчас — в блочную. Глобальная может быть лишь одна на всю программу, а блочных — огромное количество. Более того, они могут быть вложены друг в друга. Приведу пример кода:


    let userName = "Студент ";


{
 // Первый уровень вложенности
 let greet = "Привет, ";
 console.log(greet, userName);


 {
   // Второй уровень вложенности
   let question = "Как дела?";
   console.log(question);


   {
     // Третий уровень вложенности
     let message = "Сегодня хороший день для учебы!";
     console.log(message);
   }
 }
}

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

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


    let name = "Иван";

{
let age = 18;
console.log(name, age);
}

{
let name = "Петя";
let age = 23;
console.log(name, age);
}

Теперь запустим нашу программу и посмотрим, что получилось.

Скриншот: результат обновленной программы.
Результат обновленной программы.

Что мы сделали? Сейчас объясню. Иван «хранится» в глобальной области видимости и выводится в блочной. Он также мог попасть и во второй блок, но мы переопределили переменную и написали имя «Петя», поэтому в блочной области видимости вывелся Петя.

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

Функции

Функция — это фрагмент кода, который запускается «по запросу».

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


    let name = "Иван";

// мы создали функцию и назвали ее hello
function hello() {
let name = "Петя";
let age = 23;
console. log (name, age);
}

Если вы посмотрите в консоль браузера, то заметите, что в ней ничего нет. Функцию мы объявили, но не вызвали. Без этого код, который мы написали внутри hello, не заработает, как и сама функция. Однако нам просто нужно ее запустить: пропишем ниже hello(). 


    let name = "Иван";

// мы создали функцию и назвали ее hello
function hello() {
let name = "Петя";
let age = 23;
console. log (name, age);
}

// мы вызвали функцию hello
hello();

Перейдем в браузер и посмотрим на результат:

Скриншот консоли браузера: видим результат программы. Все работает!
Видим результат программы. Все работает!

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


    let name = "Иван";

// мы создали функцию и назвали ее hello
function hello() {
let name = "Петя";
let age = 23;
console. log (name, age);
}

// мы создали функцию hello
hello();
hello();
hello();
Результат будет выведен в консоли три раза.
Результат будет выведен в консоли три раза.

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

Параметры функций

Важно отметить, что функции могут принимать значения в виде параметров. Разберем на примере. 

Передадим в функцию hello данные с помощью круглых скобок: hello(userName). Далее — удалим нашу переменную, которая осталась снаружи.


    function hello(userName) {
let age = 23;
console. log (userName, age);
}

hello("Иван");

Обратите внимание: в вызове функции мы передали параметр со значением «Иван». Далее в объявлении функции задали имя переменной — это аргумент. Наше значение попало в функцию через параметр и сохранилось в аргумент функции.
Посмотрим на результат в консоли.

Скриншот консоли браузера: видим результат программы. Все работает!
Все работает! 🙂

Вызовем еще несколько функций и зададим другие имена. Также перенесем переменную age в аргумент.


    function hello(userName, age) {
console. log (userName, age);
}

hello("Иван", 23);
hello("Пётр", 25);
hello("Василий", 18);
hello("Аркадий", 30);

Посмотрим на результат в консоли браузера:

Результат выведен четыре раза.
Выглядит неплохо: результат выведен четыре раза.

Механизм функций на этом не заканчивается. Нам еще предстоит познакомиться с возвращением значений из функций, но сейчас остановимся на практике.

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


    let index = 0;
let currentYear = 2024;


document.write("<h1>Список студентов:</h1>");
let studentName = "Вася";
let dateOfBirth = 1998;
let height = 168;
let faculty = "Исторический";
let age = currentYear - dateOfBirth;
index++;


document.write(`
    <p>
        ${index}
        <strong>
            ${studentName}
        </strong>,
        Возраст:
        <strong>
            ${age}
        </strong>,
        Рост:
        <strong>
            ${height}
        </strong>,
        Факультет:
        <strong>
            ${faculty}
        </strong>
    </p>
`);

Посмотрим, что вышло в браузере:

Скриншот из браузера.

Обратите внимание, как много кода получилось. Добавим еще студента, но перед этим обернем код в блок.


    let index = 0;
let currentYear = 2024;


document.write("<h1>Список студентов:</h1>");


{
    let studentName = "Вася";
    let dateOfBirth = 1998;
    let height = 168;
    let faculty = "Исторический";
    let age = currentYear - dateOfBirth;
    index++;


    document.write(`
        <p>
            ${index}
            <strong>
                ${studentName}
            </strong>,
            Возраст:
            <strong>
                ${age}
            </strong>,
            Рост:
            <strong>
                ${height}
            </strong>,
            Факультет:
            <strong>
                ${faculty}
            </strong>
        </p>
    `);
}


{
    let studentName = "Мария";
    let dateOfBirth = 200;
    let height = 155;
    let faculty = "Юридический";
    let age = currentYear - dateOfBirth;
    index++;


    document.write(`
        <p>
            ${index}
            <strong>
                ${studentName}
            </strong>,
            Возраст:
            <strong>
                ${age}
            </strong>,
            Рост:
            <strong>
                ${height}
            </strong>,
            Факультет:
            <strong>
                ${faculty}
            </strong>
        </p>
    `);
}

Смотрим на результат:

Скриншот из браузера.

Можете видеть, как много данных придется менять вручную. Студентов может быть множество — нам не хватит и целой жизни, чтобы все заполнить вручную. А если нужно будет исправить данные? Страшно, но не для тех, кто умеет работать с функциями!

Создадим функцию printStudents(); и объявим в программе. Перенесем в нее наш код и вызовем как в примере.


    let index = 0;
let currentYear = 2024;


document.write("<h1>Список студентов:</h1>");


function printStudents() {
    let studentName = "Вася";
    let dateOfBirth = 1998;
    let height = 168;
    let faculty = "Исторический";
    let age = currentYear - dateOfBirth;
    index++;


    document.write(`
        <p>
            ${index}
            <strong>
                ${studentName}
            </strong>,
            Возраст:
            <strong>
                ${age}
            </strong>,
            Рост:
            <strong>
                ${height}
            </strong>,
            Факультет:
            <strong>
                ${faculty}
            </strong>
        </p>
    `);
}


printStudents();

Проверим в браузере, все ли работает:

Скриншот из браузера.
Информация выводится корректно.

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

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


    let index = 0;
let currentYear = 2024;


document.write("<h1>Список студентов:</h1>");


function printStudents(studentName, dateOfBirth, height, faculty) {
    let age = currentYear - dateOfBirth;
    index++;


    document.write(`
        <p>
            ${index}
            <strong>
                ${studentName}
            </strong>,
            Возраст:
            <strong>
                ${age}
            </strong>,
            Рост:
            <strong>
                ${height}
            </strong>,
            Факультет:
            <strong>
                ${faculty}
            </strong>
        </p>
    `);
}


printStudents("Вася", 1998, 168, "Исторический");
printStudents();
printStudents();

Посмотрим на результат:

Скриншот из браузера.
Работает, но неправильно

В списке видим слова undefined и NaN — типы данных, которые указывают на неточности.

  • undefined — это значение, которое указывает, что в переменную или параметр ничего не было присвоено.
  • NaN — нечисло. Это аббревиатура от Not-a-Number.

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


    let index = 0;
let currentYear = 2024;


document.write("<h1>Список студентов:</h1>");


function printStudents(studentName, dateOfBirth, height, faculty) {
    let age = currentYear - dateOfBirth;
    index++;


    document.write(`
        <p>
            ${index}
            <strong>
                ${studentName}
            </strong>,
            Возраст:
            <strong>
                ${age}
            </strong>,
            Рост:
            <strong>
                ${height}
            </strong>,
            Факультет:
            <strong>
                ${faculty}
            </strong>
        </p>
    `);
}


printStudents("Вася", 1998, 168, "Исторический");
printStudents("Юрий", 2000, 175, "Юридический");
printStudents("Мария", 2003, 155, "Биологический");

Посмотрим на результат:

Скриншот из браузера.
Вывод снова корректный.

Возврат значений из функций Return

Return — это ключевое слово, которое возвращает значение из функции. Оно работает как специальный механизм: вместо вывода данных через console.log(), как мы делали ранее, с помощью return можно передать результат работы функции для дальнейшего использования.


    let userName = "Иван";


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


let result = hello(userName); // вызываем функцию, сохраняем в переменную result


console.log(result); Выводим результат: Привет Иван

Проверим на результат в браузере:

Скриншот консоли браузера. Видим корректный вывод.
Видим корректный вывод.

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

Скриншот кода.

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

Функция — это наша учеба. Наполнение функции — различные процессы и операции. Мы — входной параметром и аргумент и без нас учеба не сдвинется с места. После учебы мы должны «вернуться» (return) домой. Главное — не забыть дневник, ведь в нем записаны результаты нашей учебы. 🙂

Заключение

Мы познакомились с работой функций, с параметрами и аргументами, а также узнали, что такое return и немного попрактиковались. В следующем тексте познакомимся с элементами веб-страниц. Следите за обновлениями в Академии Selectel!