MakeFirstStep· Frontend + ИИ

Урок 5 · JavaScript

Функции

Функция — это кусочек кода с именем, который можно запускать снова и снова. Кнопка «Купить», проверка пароля, расчёт суммы в корзине — за каждым таким действием на сайте стоит функция. Сегодня мы научимся их писать, понимать и читать чужие.

  • Объявлять функции двумя способами: Declaration и Expression
  • Писать короткие стрелочные функции
  • Передавать данные через параметры и задавать значения по умолчанию
  • Возвращать результат через return
  • Понимать, где «видна» переменная — область видимости
Как работать с этой страницей

Весь код на тёмном фоне с кнопкой ▶ Запустить — живой. Его можно менять прямо здесь и сразу видеть результат в консоли под ним. Сломали — нажмите ↺ Сброс. Подсказки к задачам спрятаны под замочком 🔒: сначала попробуйте сами, открывайте подсказку, только если застряли.

01 Что такое функция. Function Declaration

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

Без функции: повторяем одно и то же · Ctrl + Enter
console.log("Ассалому алейкум!");
console.log("Добро пожаловать в MakeFirstStep");

// ... какой-то другой код ...

console.log("Ассалому алейкум!");
console.log("Добро пожаловать в MakeFirstStep");

// ... и ещё раз ...

console.log("Ассалому алейкум!");
console.log("Добро пожаловать в MakeFirstStep");

Работает, но представьте, что текст нужно поменять. Придётся искать и исправлять его везде — и где-нибудь обязательно забудете. Функция решает эту проблему: мы один раз описываем действие и даём ему имя, а потом просто вызываем его по имени.

С функцией · Ctrl + Enter
function greet() {
  console.log("Ассалому алейкум!");
  console.log("Добро пожаловать в MakeFirstStep");
}

greet();
greet();
greet();
Аналогия из жизни

Функция — это рецепт. Рецепт оши палав записывают один раз: что взять и в каком порядке готовить. Когда хотим плов — не придумываем его заново, а открываем рецепт и готовим по нему. Записать рецепт — это объявить функцию. Приготовить по рецепту — вызвать функцию. Рецепт можно использовать сколько угодно раз.

Из чего состоит функция

Способ, который мы только что использовали, называется Function Declaration — «объявление функции». Разберём его по частям:

function greet(name) { console.log("Салом, " + name); }

greet("Мадина");
Сверху — объявление (рецепт), снизу — вызов (готовим по рецепту)
function
Ключевое слово. Говорит JavaScript: «сейчас будет функция».
Имя
Как мы будем обращаться к функции. Обычно это глагол на английском: greet, showMenu, calcTotal.
Параметры
В круглых скобках. Это «входные данные» функции. Скобки пишутся всегда, даже если они пустые.
Тело
Код в фигурных скобках { }. Выполняется каждый раз, когда функцию вызывают.
Вызов
Имя функции и круглые скобки: greet(). Именно скобки заставляют функцию сработать.

Что происходит при вызове — по шагам

Можно редактировать · Ctrl + Enter
function welcome(name) {
  console.log("Хуш омадед, " + name + "!");
}

welcome("Мадина");   // → Хуш омадед, Мадина!
welcome("Фарход");   // → Хуш омадед, Фарход!
  1. JavaScript видит объявление и запоминает: есть функция welcome. Код внутри пока не выполняется — рецепт записан, но готовить ещё не начали.
  2. Встречает вызов welcome("Мадина") и «прыгает» внутрь функции.
  3. Кладёт значение в параметр: name становится равен "Мадина".
  4. Выполняет тело — выводит строку в консоль.
  5. Возвращается туда, откуда функцию вызвали, и идёт дальше — к следующему вызову, где name уже будет "Фарход".

Как называть функции

  • Имя описывает действие: showPrice, checkPassword, sendMessage.
  • Пишем в стиле camelCase: первое слово с маленькой буквы, каждое следующее — с большой.
  • Только латиница. Кириллица технически работает, но в реальных проектах так не пишут.
  • Одна функция — одно действие. Если в имени хочется написать «и» (checkAndSendAndSave), значит, это должно быть несколько функций.
Частая ошибка

Забыть скобки при вызове. greet без скобок — это просто «упоминание» функции, она не сработает. Нужно greet().

Можно редактировать · Ctrl + Enter
function greet() {
  console.log("Салом!");
}

greet;               // ничего не произойдёт — функцию не вызвали
console.log(greet);  // → ƒ greet() — выводится сама функция, а не результат
greet();             // → Салом!

Практика: закрепляем

Начнём с простого: объявить функцию и вызвать её.

ЗАДАЧА 1.1

Приветствие академии

лёгкая

Объявите функцию sayHello, которая выводит в консоль строку Ассалому алейкум, MakeFirstStep!. Вызовите её три раза.

Можно редактировать · Ctrl + Enter
// объявите функцию sayHello здесь


// вызовите её 3 раза
Ожидаемый результат
Ассалому алейкум, MakeFirstStep!
Ассалому алейкум, MakeFirstStep!
Ассалому алейкум, MakeFirstStep!
Подсказка 1

Схема объявления: слово function, имя, пустые круглые скобки, фигурные скобки с кодом внутри.

Подсказка 2

Внутри тела — один console.log(...). Вызов — это имя и скобки: sayHello(), три строки подряд.

ЗАДАЧА 1.2

Расписание группы

лёгкая

Напишите функцию showSchedule, которая выводит расписание занятий на неделю — три строки. Вызовите функцию один раз.

Можно редактировать · Ctrl + Enter
// функция showSchedule выводит три строки расписания
Ожидаемый результат
Понедельник — HTML и CSS
Среда — JavaScript
Пятница — Практика с ИИ
Подсказка 1

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

Подсказка 2

Внутри { } — три вызова console.log, по одному на каждый день. Не забудьте вызвать функцию после объявления.

ЗАДАЧА 1.3

Хуш омадед!

средняя

Напишите функцию welcomeStudent с одним параметром name. Она должна выводить персональное приветствие. Вызовите её для трёх новых студентов: Зарины, Рустама и Нилуфар.

Можно редактировать · Ctrl + Enter
// function welcomeStudent(name) { ... }
Ожидаемый результат
Хуш омадед, Зарина! Рады видеть вас в группе.
Хуш омадед, Рустам! Рады видеть вас в группе.
Хуш омадед, Нилуфар! Рады видеть вас в группе.
Подсказка 1

Параметр name — это «пустая коробка», в которую при каждом вызове кладётся новое имя. Имя передаётся в скобках при вызове: welcomeStudent("Зарина").

Подсказка 2

Собрать строку удобно шаблонной строкой в обратных кавычках: `Хуш омадед, ${name}! ...`

02 Function Expression

В JavaScript функция — это такое же значение, как число или строка. А любое значение можно положить в переменную. Этот способ называется Function Expression — «функциональное выражение».

Можно редактировать · Ctrl + Enter
// Declaration — объявление
function sayHi() {
  console.log("Салом!");
}

// Expression — функция кладётся в переменную
const sayBye = function () {
  console.log("Хайр, то пагох!");
};

sayHi();   // → Салом!
sayBye();  // → Хайр, то пагох!

Посмотрите внимательно на второй вариант:

  • после слова function нет имени — такая функция называется анонимной. Её имя — это имя переменной sayBye;
  • мы используем const, чтобы случайно не перезаписать функцию;
  • в конце стоит точка с запятой ; — потому что это обычное присваивание, как const x = 5;.
Аналогия из жизни

Declaration — это рецепт, напечатанный в книге под заголовком «Оши палав». Expression — тот же рецепт, но записанный на карточке и положенный в коробку с подписью sayBye. Готовить можно по обоим. Разница в том, когда рецепт становится доступен — об этом ниже.

Функция как значение

Раз функция — значение, её можно передать в другую переменную. Обратите внимание: без скобок мы передаём саму функцию, а не вызываем её.

Можно редактировать · Ctrl + Enter
const greet = function (name) {
  console.log(`Салом, ${name}!`);
};

const hello = greet;   // теперь у одной функции два имени
hello("Шахром");       // → Салом, Шахром!
greet("Шахром");       // → Салом, Шахром!

Именно эта идея — «функцию можно передать как значение» — станет главной на следующем уроке, когда мы будем передавать функции в методы массивов map и filter.

Главное отличие: hoisting («поднятие»)

Перед тем как выполнять код, JavaScript быстро просматривает файл и заранее запоминает все функции, объявленные через Declaration. Поэтому их можно вызывать даже выше того места, где они написаны. Это называется hoisting — «поднятие».

Можно редактировать · Ctrl + Enter
showMenu(); // → Меню: самбуса, курутоб, чой — работает, хотя функция ниже!

function showMenu() {
  console.log("Меню: самбуса, курутоб, чой");
}

С Expression так не получится: переменная const появляется только в той строке, где её объявили. До этой строки её просто нет.

Этот код выдаст ошибку · Ctrl + Enter
showPrices(); // ✖ ошибка: обращаемся к переменной раньше, чем она создана

const showPrices = function () {
  console.log("Самбуса — 5 сомони");
};
Function DeclarationFunction Expression
Как выглядитfunction f() {}const f = function () {};
Можно вызвать до объявления?Да (hoisting)Нет — будет ошибка
Точка с запятой в концеНе нужнаНужна
Когда использоватьОсновные функции программыКогда функцию нужно передать или сохранить как значение
Совет

Даже если Declaration позволяет вызывать функцию «до» объявления, лучше так не делать. Код читается сверху вниз: сначала объявили — потом используем. Так его проще понимать и вам, и коллегам, и ИИ-помощнику.

Практика: закрепляем

Тренируем запись через переменную и разбираемся с поднятием.

ЗАДАЧА 2.1

Перепишите на Expression

лёгкая

Ниже функция в виде Declaration. Перепишите её в виде Function Expression с тем же именем и вызовите. Результат не должен измениться.

Было (только читать)
function showAddress() {
  console.log("MakeFirstStep — Душанбе, проспект Рудаки");
}
showAddress();
Ваш вариант · Ctrl + Enter
// ваша Function Expression с именем showAddress
showAddress();
Ожидаемый результат
MakeFirstStep — Душанбе, проспект Рудаки
Подсказка 1

Имя функции становится именем переменной: const showAddress = ...

Подсказка 2

После знака = пишется function () { ... } без имени, а в самом конце — точка с запятой.

ЗАДАЧА 2.2

Предскажите результат

средняя

Не запуская код, ответьте устно или в тетради: что выведет первая строка? Что произойдёт на третьей? Затем запустите и проверьте себя. После этого исправьте код так, чтобы обе функции сработали, а выражение hi осталось Expression.

Можно редактировать · Ctrl + Enter
hello();
function hello() {
  console.log("Declaration сработал!");
}

hi();
const hi = function () {
  console.log("Expression сработал!");
};
Ожидаемый результат после исправления
Declaration сработал!
Expression сработал!
Подсказка 1

Вспомните, какой из двух способов JavaScript «поднимает» наверх, а какой — нет.

Подсказка 2

Ошибку даёт вызов hi(): в момент вызова переменная hi ещё не создана. Подумайте, куда нужно переставить одну строку.

ЗАДАЧА 2.3

Ценники в чайхоне

средняя

Создайте через Function Expression функцию showPrice с двумя параметрами: dish (название блюда) и price (цена). Она выводит ценник. Вызовите её для трёх блюд.

Можно редактировать · Ctrl + Enter
// const showPrice = ...

// Самбуса — 5, Курутоб — 35, Шакароб — 15
Ожидаемый результат
Самбуса — 5 сомони
Курутоб — 35 сомони
Шакароб — 15 сомони
Подсказка 1

Параметры перечисляются через запятую: function (dish, price). При вызове аргументы передаются в том же порядке.

Подсказка 2

Шаблон строки: `${dish} — ${price} сомони`. Вызов выглядит как showPrice("Самбуса", 5);

03 Параметры, аргументы и значения по умолчанию

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

Аналогия из жизни

Приложение такси. В нём есть форма с полями «Откуда» и «Куда» — это параметры: место для данных. Когда вы заказываете машину и пишете «Сино» и «Корвон» — это аргументы: конкретные значения, которые попали в эти поля. Форма одна, а поездки каждый раз разные.

Параметр
Имя в скобках при объявлении функции: function orderTaxi(from, to). Внутри функции это обычная переменная.
Аргумент
Конкретное значение при вызове: orderTaxi("Сино", "Корвон").
Можно редактировать · Ctrl + Enter
function orderTaxi(from, to) {
  console.log(`Такси: ${from} → ${to}`);
}

orderTaxi("Сино", "Корвон");        // → Такси: Сино → Корвон
orderTaxi("Аэропорт", "Ботсад");    // → Такси: Аэропорт → Ботсад

Порядок имеет значение

Аргументы попадают в параметры строго по порядку: первый — в первый, второй — во второй. Имена переменных при вызове роли не играют.

Можно редактировать · Ctrl + Enter
function orderTaxi(from, to) {
  console.log(`Такси: ${from} → ${to}`);
}

orderTaxi("Корвон", "Сино");   // → Такси: Корвон → Сино — поменяли местами, поехали в обратную сторону!

Если аргументов меньше или больше

JavaScript не ругается, если аргументов передали не столько, сколько параметров:

  • не хватает аргумента — параметр получает значение undefined («не определено»);
  • лишние аргументы — просто игнорируются.
Можно редактировать · Ctrl + Enter
function orderTaxi(from, to) {
  console.log(`Такси: ${from} → ${to}`);
}

orderTaxi("Сино");                          // → Такси: Сино → undefined
orderTaxi("Сино", "Корвон", "с кондиционером"); // → Такси: Сино → Корвон

Значения по умолчанию

Чтобы вместо undefined было что-то осмысленное, параметру можно задать значение по умолчанию прямо в скобках, через знак =. Оно сработает, только если аргумент не передали.

Можно редактировать · Ctrl + Enter
function greet(name = "гость") {
  console.log(`Салом, ${name}!`);
}

greet("Далер");  // → Салом, Далер!
greet();         // → Салом, гость!
Можно редактировать · Ctrl + Enter
function makeTea(sort = "зелёный", sugar = 0) {
  console.log(`Чой: ${sort}, сахара: ${sugar} ложки`);
}

makeTea();                 // → Чой: зелёный, сахара: 0 ложки
makeTea("чёрный");         // → Чой: чёрный, сахара: 0 ложки
makeTea("чёрный", 2);      // → Чой: чёрный, сахара: 2 ложки
makeTea(undefined, 2);     // → Чой: зелёный, сахара: 2 ложки

Обратите внимание на последнюю строку. Чтобы «пропустить» первый аргумент и задать второй, передают undefined — тогда сработает значение по умолчанию.

Ловушка

Значение по умолчанию срабатывает только для undefined. Если передать 0, "" (пустую строку) или null — будет использовано именно это значение, а не значение по умолчанию.

Можно редактировать · Ctrl + Enter
function setVolume(level = 50) {
  console.log("Громкость:", level);
}

setVolume();          // → Громкость: 50
setVolume(0);         // → Громкость: 0   — ноль это настоящее значение
setVolume(undefined); // → Громкость: 50
Совет

Параметры со значением по умолчанию ставьте в конец списка. Сначала обязательные данные, потом необязательные: function bookTicket(city, seat = "у окна").

Практика: закрепляем

Параметры — то, без чего не обходится ни одна реальная функция.

ЗАДАЧА 3.1

Маршрутка

лёгкая

Напишите функцию showRoute(number, from, to), которая выводит информацию о маршрутке. Вызовите её для двух маршрутов из примера. Затем вызовите её, передав только номер, и посмотрите, что получится.

Можно редактировать · Ctrl + Enter
// showRoute(8, "Зелёный базар", "Испечак")
// showRoute(22, "Шохмансур", "92-й мкр")
Ожидаемый результат
Маршрутка №8: Зелёный базар → Испечак
Маршрутка №22: Шохмансур → 92-й мкр
Маршрутка №5: undefined → undefined
Подсказка 1

Три параметра — три значения через запятую и в скобках при объявлении, и при вызове.

Подсказка 2

Для последней строки вызовите showRoute(5). Подумайте, почему from и to стали undefined.

ЗАДАЧА 3.2

Гость или студент

лёгкая

Напишите функцию enterRoom(name, room). Если имя не передали, вместо него должно быть гость. Если не передали аудиторию — 101.

Можно редактировать · Ctrl + Enter
// function enterRoom(...) { ... }

enterRoom("Сабрина", 204);
enterRoom("Абдулло");
enterRoom();
Ожидаемый результат
Сабрина, проходите в аудиторию 204
Абдулло, проходите в аудиторию 101
гость, проходите в аудиторию 101
Подсказка 1

Значение по умолчанию пишется прямо в скобках: (name = ..., room = ...).

Подсказка 2

Строка "гость" — в кавычках, число 101 — без кавычек.

ЗАДАЧА 3.3

Билет на поезд

средняя

Функция bookTicket(city, seat, travelClass) выводит информацию о билете. Город обязателен. Место по умолчанию — у окна, класс по умолчанию — эконом. Сделайте три вызова, чтобы получить ровно такой результат. В третьем вызове нужно задать класс, но место оставить по умолчанию.

Можно редактировать · Ctrl + Enter
// function bookTicket(...) { ... }
Ожидаемый результат
Билет: Душанбе → Худжанд, место: у окна, класс: эконом
Билет: Душанбе → Бохтар, место: у прохода, класс: эконом
Билет: Душанбе → Куляб, место: у окна, класс: купе
Подсказка 1

У seat и travelClass есть значения по умолчанию, у city — нет.

Подсказка 2

Чтобы пропустить второй аргумент, но передать третий, на место второго поставьте undefined.

04 return — функция возвращает результат

До сих пор наши функции только показывали что-то в консоли. Но чаще функция должна посчитать результат и отдать его нам, чтобы мы могли дальше с ним работать: сложить, сравнить, показать на странице. Для этого есть слово return — «вернуть».

Можно редактировать · Ctrl + Enter
function sum(a, b) {
  return a + b;
}

const result = sum(10, 5);
console.log(result);          // → 15
console.log(sum(2, 3) * 10);  // → 50

Когда функция встречает return, она отдаёт значение туда, где её вызвали. Можно представить, что вызов sum(10, 5) как бы заменяется результатом — числом 15. Поэтому вызов функции можно положить в переменную, подставить в выражение или передать в другую функцию.

Аналогия из жизни

Вы даёте продавцу на Шохмансуре 100 сомони за покупку в 70. Продавец считает и возвращает вам сдачу — 30 сомони. Эти деньги теперь у вас в руках: можно потратить, отложить, пересчитать. Это и есть return. А console.log — это если продавец просто громко скажет «сдача 30!», но денег не даст. Услышали — и всё, использовать нечего.

console.log и return — не одно и то же

Это самая частая путаница у начинающих. Сравните:

Только выводит

Результат показан, но получить его нельзя.

Можно редактировать · Ctrl + Enter
function getChange(paid, price) {
  console.log(paid - price);
}

const change = getChange(100, 70);
// → 30 (вывела сама функция)
console.log("Сдача:", change);
// → Сдача: undefined 😕
Возвращает

Результат можно сохранить и использовать.

Можно редактировать · Ctrl + Enter
function getChange(paid, price) {
  return paid - price;
}

const change = getChange(100, 70);
console.log("Сдача:", change);
// → Сдача: 30 ✓

Правило: если функция что-то считает — пусть возвращает результат через return. А решать, выводить его в консоль или на страницу, будет код, который эту функцию вызвал.

Без return функция возвращает undefined

Можно редактировать · Ctrl + Enter
function doNothing() {
  const x = 5;
}

console.log(doNothing()); // → undefined

return сразу завершает функцию

После return функция прекращает работу. Код ниже него уже не выполнится.

Можно редактировать · Ctrl + Enter
function test() {
  console.log("Шаг 1");
  return "готово";
  console.log("Шаг 2"); // эта строка никогда не выполнится
}

console.log(test());
// → Шаг 1
// → готово

Этим часто пользуются, чтобы выйти из функции пораньше, если что-то не так. Такой приём называют «ранний выход» (guard).

Можно редактировать · Ctrl + Enter
function canEnroll(age) {
  if (age < 14) {
    return "Пока рано: на курс принимают с 14 лет";
  }
  return "Добро пожаловать на курс!";
}

console.log(canEnroll(12)); // → Пока рано: на курс принимают с 14 лет
console.log(canEnroll(17)); // → Добро пожаловать на курс!

Заметьте: else здесь не нужен. Если первое условие сработало, функция уже вышла на первом return и до второго не дойдёт.

Функция может вернуть true или false

Функции-проверки обычно возвращают логическое значение. Их принято называть с is, has или can в начале:

Можно редактировать · Ctrl + Enter
function isAdult(age) {
  return age >= 18;
}

console.log(isAdult(20)); // → true
console.log(isAdult(15)); // → false

if (isAdult(19)) {
  console.log("Можно получить водительские права");
}

Функции работают вместе

Результат одной функции можно сразу передать в другую. Так из маленьких простых функций собирают большие программы.

Можно редактировать · Ctrl + Enter
function getTotal(price, count) {
  return price * count;
}

function addDelivery(total) {
  return total + 10;
}

const order = addDelivery(getTotal(35, 3)); // 3 курутоба по 35 + доставка 10
console.log(`К оплате: ${order} сомони`);  // → К оплате: 115 сомони
Ловушка

Не переносите значение на следующую строку после return. JavaScript сам поставит точку с запятой сразу после слова return, и функция вернёт undefined.

Как НЕ надо · Ctrl + Enter
function getCity() {
  return
    "Душанбе";
}

console.log(getCity()); // → undefined — значение «потерялось»

Практика: закрепляем

Во всех задачах ниже функция должна возвращать результат, а выводит его код снаружи.

ЗАДАЧА 4.1

Сумма покупок

лёгкая

Напишите функцию sum(a, b), которая возвращает сумму двух чисел. Используя только её (без знака + снаружи функции), посчитайте стоимость покупки: нон за 4 сомони, молоко за 12 и зардолу за 25.

Можно редактировать · Ctrl + Enter
// function sum(a, b) { ... }

// const total = ...
// console.log(...)
Ожидаемый результат
Итого: 41 сомони
Подсказка 1

Функция умеет складывать только два числа. Но её результат — тоже число, и его можно передать в неё же.

Подсказка 2

Попробуйте вложенный вызов: sum(sum(___, ___), ___).

ЗАДАЧА 4.2

Скидка на Корвоне

средняя

Напишите функцию getDiscountPrice(price, percent), которая возвращает цену после скидки. Проверьте на двух товарах.

Можно редактировать · Ctrl + Enter
// function getDiscountPrice(price, percent) { ... }

console.log("Куртка:", getDiscountPrice(400, 25));
console.log("Кроссовки:", getDiscountPrice(350, 10));
Ожидаемый результат
Куртка: 300
Кроссовки: 315
Подсказка 1

Сначала найдите размер скидки в сомони: сколько составляет percent процентов от price.

Подсказка 2

Скидка = price * percent / 100. Цена после скидки — это исходная цена минус скидка. Не забудьте return.

ЗАДАЧА 4.3

Когда можно получить паспорт

сложная

В Таджикистане паспорт получают с 16 лет. Напишите функцию checkPassport(age): если возраст 16 или больше, она возвращает строку Можно получить паспорт, иначе — сколько лет осталось ждать. Используйте ранний выход через return, без else.

Можно редактировать · Ctrl + Enter
// function checkPassport(age) { ... }

console.log(checkPassport(18));
console.log(checkPassport(16));
console.log(checkPassport(13));
Ожидаемый результат
Можно получить паспорт
Можно получить паспорт
Рано: осталось лет — 3
Подсказка 1

Сначала проверьте «хороший» случай через if и сразу верните строку. Если функция не вышла — значит, возраст меньше 16.

Подсказка 2

Сколько лет осталось: 16 - age. Соберите строку шаблоном `Рано: осталось лет — ${...}` и верните её.

05 Стрелочные функции

Стрелочная функция (arrow function) — это короткая запись Function Expression. Своё название она получила из-за знака =>, похожего на стрелку. В современном коде, в React и в коде, который пишет ИИ, вы будете встречать её постоянно.

Превращаем обычную функцию в стрелочную — по шагам

  1. Исходная функция — Expression
    JavaScript
    const double = function (n) {
      return n * 2;
    };
  2. Убираем слово function, после скобок ставим стрелку =>
    JavaScript
    const double = (n) => {
      return n * 2;
    };
  3. Если в теле только return — убираем фигурные скобки и само слово return. Значение вернётся автоматически.
    JavaScript
    const double = (n) => n * 2;
  4. Если параметр ровно один — можно убрать и круглые скобки
    JavaScript
    const double = n => n * 2;

Все четыре варианта делают одно и то же. Проверьте:

Можно редактировать · Ctrl + Enter
const double = n => n * 2;

console.log(double(5));   // → 10
console.log(double(21));  // → 42

Правила записи

СитуацияКак пишем
Нет параметровconst hi = () => "Салом!"; — скобки обязательны
Один параметрconst double = n => n * 2; — скобки можно опустить
Несколько параметровconst sum = (a, b) => a + b; — скобки обязательны
Одно выражениеБез { } — результат возвращается сам
Несколько строкС { } — и тогда return пишем сами
Можно редактировать · Ctrl + Enter
const sayHi = () => "Салом!";
const sum = (a, b) => a + b;
const isEven = n => n % 2 === 0;

// несколько строк — нужны фигурные скобки и return
const getBill = (price, people) => {
  const tip = price * 0.1;
  return (price + tip) / people;
};

console.log(sayHi());          // → Салом!
console.log(sum(7, 8));        // → 15
console.log(isEven(10));       // → true
console.log(getBill(200, 4));  // → 55
Частая ошибка

Поставить фигурные скобки и забыть return. Как только появились { }, автоматический возврат исчезает — функция вернёт undefined.

Ошибка
Можно редактировать · Ctrl + Enter
const triple = n => { n * 3 };
console.log(triple(4)); // → undefined
Правильно
Можно редактировать · Ctrl + Enter
const triple = n => n * 3;
console.log(triple(4)); // → 12

Когда какую функцию использовать

  • Стрелочная — для коротких функций и особенно когда функцию передают в другую функцию. На следующем уроке вы увидите, как красиво они смотрятся в методах массивов: prices.map(p => p * 2).
  • Declaration — для крупных, «главных» функций программы, у которых важное имя.
  • У стрелочных функций есть одна особенность, связанная со словом this. Её мы разберём на уроке про объекты, а пока просто запомните, что она существует.
ИИ-подсказка

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

Практика: закрепляем

Цель — чтобы стрелочная запись читалась так же легко, как обычная.

ЗАДАЧА 5.1

Перепишите стрелками

лёгкая

Перепишите все три функции в виде стрелочных, сделав запись как можно короче. Вызовы внизу менять не нужно — результат должен остаться прежним.

Было (только читать)
function square(n) {
  return n * n;
}
function greet(name) {
  return `Салом, ${name}!`;
}
function getRandomDice() {
  return 4; // честно выбрано броском кубика 🎲
}
Ваш вариант · Ctrl + Enter
// ваши три стрелочные функции: square, greet, getRandomDice

console.log(square(9));
console.log(greet("Манижа"));
console.log(getRandomDice());
Ожидаемый результат
81
Салом, Манижа!
4
Подсказка 1

Каждую функцию запишите как const имя = (...) => ...;. В каждой только один return — значит, фигурные скобки можно убрать.

Подсказка 2

У getRandomDice нет параметров — пустые скобки () оставить обязательно.

ЗАДАЧА 5.2

Обмен валюты

средняя

Напишите две стрелочные функции в одну строку каждая: toSomoni(usd) переводит доллары в сомони, toUsd(somoni) — обратно. Курс возьмём условный: 1 доллар = 11 сомони.

Можно редактировать · Ctrl + Enter
const RATE = 11;

// const toSomoni = ...
// const toUsd = ...

console.log(toSomoni(100));
console.log(toUsd(550));
console.log(toUsd(toSomoni(25)));
Ожидаемый результат
1100
50
25
Подсказка 1

Доллары в сомони — умножаем на курс, сомони в доллары — делим на курс.

Подсказка 2

Одна строка: const toSomoni = usd => ___ * RATE;. Переменная RATE объявлена снаружи, но функция её видит — почему, узнаем в следующем разделе.

ЗАДАЧА 5.3

Сколько ехать

сложная

Напишите стрелочную функцию travelTime(distance, speed), которая возвращает время в пути в часах. Скорость по умолчанию — 60 км/ч. Затем напишите вторую стрелочную функцию tripInfo(city, distance, speed), которая использует первую и возвращает готовую строку.

Можно редактировать · Ctrl + Enter
// const travelTime = ...
// const tripInfo = ...

console.log(travelTime(120));
console.log(tripInfo("Хорог", 525));
console.log(tripInfo("Худжанд", 340, 85));
Ожидаемый результат
2
Душанбе → Хорог: 525 км, примерно 8.75 ч
Душанбе → Худжанд: 340 км, примерно 4 ч
Подсказка 1

Время = расстояние / скорость. Значение по умолчанию у стрелочных функций задаётся так же: (distance, speed = 60) => ...

Подсказка 2

Внутри шаблонной строки tripInfo вызовите travelTime(distance, speed). Если speed не передали, туда уйдёт undefined — и в travelTime сработает значение по умолчанию.

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

Область видимости (scope) отвечает на вопрос: в каком месте кода переменная «видна» и её можно использовать. От этого зависит, почему иногда код выдаёт ошибку is not defined, хотя переменная «вот же она, написана».

Аналогия из жизни

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

Глобальная область — «двор» const city = "Душанбе";
Область функции — «квартира» const student = "Мадина"; // видит city
Блок { } — «комната» const grade = 5; // видит student и city
Каждая внутренняя область видит всё, что снаружи. Внешняя — не видит того, что внутри.

1. Глобальная область

Переменные, объявленные вне всех функций и блоков. Видны везде в программе.

Можно редактировать · Ctrl + Enter
const academy = "MakeFirstStep";

function showAcademy() {
  console.log(`Учимся в ${academy}`); // функция видит глобальную переменную
}

showAcademy();         // → Учимся в MakeFirstStep
console.log(academy);  // → MakeFirstStep

2. Область функции (локальная)

Переменные, объявленные внутри функции, существуют только внутри неё. Параметры функции — тоже локальные переменные. Снаружи их не видно.

Этот код выдаст ошибку · Ctrl + Enter
function makeOrder() {
  const dish = "оши палав";
  console.log(`Заказ: ${dish}`);
}

makeOrder();       // → Заказ: оши палав
console.log(dish); // ✖ ReferenceError: dish is not defined

Это не баг, а очень полезное свойство. Каждая функция — как отдельная квартира: можно спокойно называть переменные внутри, не боясь, что они «перепутаются» с переменными в другой функции.

Можно редактировать · Ctrl + Enter
function morning() {
  const message = "Субх ба хайр!";
  console.log(message);
}

function evening() {
  const message = "Шаб ба хайр!"; // такое же имя — никакого конфликта
  console.log(message);
}

morning(); // → Субх ба хайр!
evening(); // → Шаб ба хайр!

3. Блочная область

Любые фигурные скобки { } — в if, for, while — тоже создают свою область. Переменные let и const, объявленные в блоке, видны только внутри этого блока.

Можно редактировать · Ctrl + Enter
const score = 92;

if (score >= 86) {
  const grade = 5;
  console.log("Оценка внутри блока:", grade); // → Оценка внутри блока: 5
}

console.log(typeof grade); // → undefined — снаружи блока grade не существует

Затенение: одинаковые имена

Если внутри функции объявить переменную с тем же именем, что и снаружи, внутренняя закроет («затенит») внешнюю. Внешняя при этом не меняется.

Можно редактировать · Ctrl + Enter
const weather = "солнечно";

function showMountainWeather() {
  const weather = "снег"; // своя, локальная переменная
  console.log("В Варзобе:", weather);
}

showMountainWeather();             // → В Варзобе: снег
console.log("В Душанбе:", weather); // → В Душанбе: солнечно

JavaScript ищет переменную изнутри наружу: сначала в текущей области, потом в той, что снаружи, и так до глобальной. Берёт первую найденную. Если не нашёл нигде — ошибка is not defined.

Как достать значение из функции наружу

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

Можно редактировать · Ctrl + Enter
function getDish() {
  const dish = "оши палав";
  return dish;
}

const myDish = getDish();
console.log(myDish); // → оши палав
Важно: а как же var?

В старом коде (и иногда в ответах ИИ) встречается var. Он не подчиняется блочной области — «протекает» за фигурные скобки if и for. Из-за этого возникают трудноуловимые ошибки. В современном коде пишем только const (по умолчанию) и let (если значение будет меняться).

Можно редактировать · Ctrl + Enter
if (true) {
  var oldStyle = "я протёк наружу";
  let newStyle = "я остался внутри";
}

console.log(oldStyle);        // → я протёк наружу
console.log(typeof newStyle); // → undefined
Совет

Объявляйте переменную в самой маленькой области, где она нужна. Глобальные переменные может случайно изменить любая функция в программе — и потом очень трудно найти, кто это сделал. Чем меньше глобальных переменных, тем спокойнее жизнь.

Практика: закрепляем

Здесь важно не только написать код, но и предсказать, как он себя поведёт.

ЗАДАЧА 6.1

Кто что видит

лёгкая

Не запуская код, запишите в тетрадь, что выведет каждая из трёх строк с console.log. Затем запустите и сверьтесь. Для каждой строки объясните, какую из переменных name нашёл JavaScript и почему.

Можно редактировать · Ctrl + Enter
const name = "MakeFirstStep";

function first() {
  const name = "Фарход";
  console.log("1:", name);
}

function second() {
  console.log("2:", name);
}

first();
second();
console.log("3:", name);
Ожидаемый результат
Сначала ваш прогноз — потом кнопка «Запустить»
Подсказка 1

Вспомните правило поиска: JavaScript ищет переменную сначала в текущей области, потом выходит наружу.

Подсказка 2

У функции first есть собственная name. А у second своей нет — куда ей придётся «посмотреть»?

ЗАДАЧА 6.2

Почините код

средняя

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

Можно редактировать · Ctrl + Enter
function calcCart(price, count) {
  const total = price * count;
}

calcCart(15, 4);
console.log(`Сумма корзины: ${total} сомони`);
Ожидаемый результат
Сумма корзины: 60 сомони
Подсказка 1

Прочитайте текст ошибки в консоли. total объявлена внутри функции — в какой области она видна?

Подсказка 2

Функция должна вернуть total, а снаружи результат вызова нужно сохранить в переменную: const total = calcCart(...).

ЗАДАЧА 6.3

Счётчик посетителей

сложная

На входе в библиотеку стоит счётчик. Напишите функцию addVisitor(name), которая при каждом вызове увеличивает общее число посетителей на 1 и выводит строку, как в примере. Вызовите её для трёх посетителей. Затем ответьте письменно: почему переменную-счётчик нельзя объявить внутри функции? Проверьте свой ответ — перенесите её внутрь и запустите.

Можно редактировать · Ctrl + Enter
// где объявить счётчик?

// function addVisitor(name) { ... }

addVisitor("Сабрина");
addVisitor("Далер");
addVisitor("Манижа");
Ожидаемый результат
Добро пожаловать, Сабрина! Посетителей сегодня: 1
Добро пожаловать, Далер! Посетителей сегодня: 2
Добро пожаловать, Манижа! Посетителей сегодня: 3
Подсказка 1

Счётчик должен «жить» между вызовами функции. Переменные внутри функции создаются заново при каждом вызове — и при каждом вызове начинаются с нуля.

Подсказка 2

Объявите let visitors = 0; снаружи функции, а внутри увеличивайте: visitors++.

07 Итоговая практика

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

Как решать большую задачу

1) Прочитайте условие дважды. 2) Выпишите, что функция получает (параметры) и что возвращает. 3) Решите на конкретном примере в уме или на бумаге. 4) Только потом пишите код — и проверяйте его кнопкой «Запустить» после каждого шага.

Практика: собираем всё вместе

Три задачи — три маленькие программы.

ЗАДАЧА 7.1

Счёт в чайхоне

средняя

Компания друзей поужинала в чайхоне. Напишите функцию splitBill(total, people, tipPercent), которая возвращает, сколько должен заплатить каждый с учётом чаевых. Чаевые по умолчанию — 10%. Результат округлите до целого числа с помощью Math.round().

Можно редактировать · Ctrl + Enter
// function splitBill(...) { ... }

console.log(splitBill(360, 4));
console.log(splitBill(250, 3, 15));
console.log(splitBill(500, 5, 0));
Ожидаемый результат
99
96
100
Подсказка 1

Порядок действий: посчитать чаевые → прибавить к сумме → разделить на количество людей → округлить.

Подсказка 2

Сумма с чаевыми: total + total * tipPercent / 100. Обратите внимание на третий вызов: 0 — это настоящее значение, значение по умолчанию тут не сработает (и не должно).

ЗАДАЧА 7.2

Погода в Душанбе

средняя

Напишите две функции. Стрелочная toFahrenheit(c) переводит градусы Цельсия в Фаренгейты по формуле c × 9 / 5 + 32. Функция describeWeather(c) использует первую и возвращает строку: от 30 °C и выше — жарко, от 15 — тепло, ниже — прохладно. Используйте ранний return.

Можно редактировать · Ctrl + Enter
// const toFahrenheit = ...
// function describeWeather(c) { ... }

console.log(describeWeather(38));
console.log(describeWeather(22));
console.log(describeWeather(5));
Ожидаемый результат
38°C (100.4°F) — жарко
22°C (71.6°F) — тепло
5°C (41°F) — прохладно
Подсказка 1

Сначала посчитайте Фаренгейты в переменную внутри describeWeather, чтобы не вызывать функцию несколько раз.

Подсказка 2

Проверки идут от большей температуры к меньшей: if (c >= 30) return ...; затем if (c >= 15) return ...;, а последний return — для всех остальных случаев.

ЗАДАЧА 7.3

Ведомость экзамена

сложная

Преподаватель переводит баллы (от 0 до 100) в оценки: 86 и выше — 5, от 71 — 4, от 56 — 3, ниже — 2. Напишите:

  • getGrade(score) — возвращает оценку числом;
  • isPassed(score) — стрелочная, возвращает true, если оценка 3 и выше (используйте getGrade внутри);
  • report(name, score) — возвращает строку для ведомости, используя обе функции.
Можно редактировать · Ctrl + Enter
// function getGrade(score) { ... }
// const isPassed = ...
// function report(name, score) { ... }

console.log(report("Рустам", 87));
console.log(report("Зарина", 72));
console.log(report("Шахром", 56));
console.log(report("Далер", 50));
Ожидаемый результат
Рустам: 87 баллов, оценка 5 — сдал
Зарина: 72 баллов, оценка 4 — сдал
Шахром: 56 баллов, оценка 3 — сдал
Далер: 50 баллов, оценка 2 — пересдача
Подсказка 1

Начните с getGrade и проверьте её отдельно: console.log(getGrade(90)). Только когда она работает — переходите к следующей функции. Так строят программы из маленьких надёжных кирпичиков.

Подсказка 2

isPassed в одну строку: score => getGrade(score) >= 3. В report слово «сдал» или «пересдача» удобно выбрать тернарным оператором: isPassed(score) ? "сдал" : "пересдача".

✓ Шпаргалка урока

  • Функция — именованный кусок кода. Объявили один раз — вызываем сколько угодно: greet().
  • Declaration: function greet() {} — можно вызвать до объявления (hoisting).
  • Expression: const greet = function () {}; — функция как значение в переменной, доступна только после объявления.
  • Стрелочная: const double = n => n * 2; — без { } результат возвращается сам; с { } нужен return.
  • Параметры — имена при объявлении, аргументы — значения при вызове. Передаются по порядку. Не передали — undefined.
  • По умолчанию: function f(x = 10) — срабатывает только для undefined.
  • return отдаёт результат и сразу завершает функцию. Без него функция возвращает undefined. Считаем — возвращаем, а не выводим.
  • Область видимости: изнутри видно наружу, снаружи внутрь — нет. let/const живут в своих { }. var не используем.