Объявление функций и return
Функция — это один из самых главных строительных блоков в программировании. Здесь разберём: зачем они вообще нужны, как их объявлять двумя способами, что такое return и почему без него функция возвращает undefined.
🤔 Зачем вообще нужны функции?
Представьте, что вы пишете программу для расчёта площади нескольких фигур. Без функций ваш код выглядел бы так:
// Площадь прямоугольника 1
let width1 = 5;
let height1 = 3;
let area1 = width1 * height1;
console.log("Площадь 1:", area1);
// Площадь прямоугольника 2
let width2 = 10;
let height2 = 4;
let area2 = width2 * height2;
console.log("Площадь 2:", area2);
// Площадь прямоугольника 3
let width3 = 7;
let height3 = 2;
let area3 = width3 * height3;
console.log("Площадь 3:", area3);
Всё работает, но вы трижды написали одну и ту же логику! А теперь представьте, что требования изменились — площадь нужно выводить в квадратных метрах с двумя знаками после запятой. Вам придётся найти и исправить три места в коде. Если таких мест 50 — шансов не пропустить ни одно практически нет.
💡 Принцип DRY (Don't Repeat Yourself — «не повторяйся»): каждый кусок логики должен жить в одном месте. Функции — главный инструмент соблюдения этого принципа.
Функции решают две ключевые проблемы:
Написал один раз — вызываешь сколько угодно раз. Изменил в одном месте — изменилось везде.
Разбиваешь большую задачу на маленькие понятные части. Каждая функция делает одну конкретную вещь.
Вызов calculateArea(5, 3) читается как книга. Не нужно разбираться в деталях реализации каждый раз.
📝 Способ 1: Function Declaration (объявление функции)
Первый и самый классический способ создать функцию — это function declaration (объявление функции). Начинается с ключевого слова function, затем имя функции, затем круглые скобки, затем тело в фигурных скобках.
function имяФункции(параметры) {
// тело функции — код, который выполнится при вызове
}
Реальный пример — функция приветствия:
// Объявление функции
function greet(name) {
console.log("Привет, " + name + "!");
}
// Вызов функции — просто пишем имя и скобки
greet("Иван"); // Привет, Иван!
greet("Мария"); // Привет, Мария!
greet("Алекс"); // Привет, Алекс!
Разберём каждую часть по отдельности:
function— ключевое слово, говорит JavaScript: «дальше идёт функция»greet— имя функции. Называй глаголом или глагол+существительное:greet,calculateArea,sendEmail(name)— параметр: переменная, которая получит значение при вызове. Может быть несколько через запятую{ ... }— тело функции: код, который выполнится каждый раз при вызовеgreet("Иван")— вызов функции. В скобках — аргумент, значение которое подставится вname
Ещё пример — функция с несколькими параметрами, вычисляющая площадь прямоугольника:
function calculateArea(width, height) {
let area = width * height;
console.log("Площадь:", area);
}
calculateArea(5, 3); // Площадь: 15
calculateArea(10, 4); // Площадь: 40
calculateArea(7, 2); // Площадь: 14
Теперь если нужно изменить формат вывода — исправляем только функцию в одном месте.
📌 Способ 2: Function Expression (функциональное выражение)
Второй способ — function expression. Здесь функция создаётся как значение и присваивается переменной. Выглядит почти так же, но есть важные отличия.
// Function Expression — функция как значение переменной
const greet = function(name) {
console.log("Привет, " + name + "!");
};
// Вызов — такой же, через имя переменной и скобки
greet("Иван"); // Привет, Иван!
greet("Мария"); // Привет, Мария!
👀 Обратите внимание: после закрывающей фигурной скобки стоит точка с запятой ;. Это потому что мы присваиваем значение переменной, а присваивание — это выражение, которое заканчивается точкой с запятой.
Главная практическая разница между двумя способами — в hoisting (поднятии). Об этом подробно поговорим в уроке 6.5. Пока запомните основное:
Можно вызвать до объявления в коде. JavaScript «поднимает» её наверх файла автоматически.
greet("Иван"); // Работает!
function greet(name) {
console.log("Привет, " + name);
}
Нельзя вызвать до строки с присваиванием. Переменная ещё не имеет значения.
greet("Иван"); // Ошибка!
const greet = function(name) {
console.log("Привет, " + name);
};
На практике оба способа широко используются. Function declaration — чаще для именованных «рабочих» функций программы. Function expression — чаще когда функцию нужно передать как аргумент или сохранить в объект.
↩️ Ключевое слово return
Пока наши функции только выводили текст через console.log. Но функции могут возвращать значение — то есть производить результат, который можно сохранить в переменную или использовать дальше.
Ключевое слово return делает именно это: возвращает значение из функции наружу — туда, где функция была вызвана.
// Функция БЕЗ return — только выводит
function showArea(width, height) {
console.log(width * height); // просто печатает
}
// Функция С return — возвращает значение
function calculateArea(width, height) {
return width * height; // возвращает число
}
// Разница при использовании:
showArea(5, 3); // Выведет 15, но нельзя сохранить
let area = calculateArea(5, 3); // area = 15, можно использовать дальше!
console.log(area); // 15
console.log(area * 2); // 30 — используем результат в вычислениях
console.log("Площадь: " + area + " кв.м"); // "Площадь: 15 кв.м"
💡 Правило большого пальца: Если функция что-то вычисляет — используй return. Если функция что-то делает (отправляет email, рисует на экране) — return часто не нужен.
Ещё пример с функцией проверки на чётность:
function isEven(number) {
return number % 2 === 0; // возвращает true или false
}
console.log(isEven(4)); // true
console.log(isEven(7)); // false
// Результат можно использовать в условии:
if (isEven(10)) {
console.log("Число чётное!");
}
🚪 Ранний return — выход из функции
return делает две вещи одновременно: возвращает значение и немедленно завершает функцию. Код после return никогда не выполнится.
Это очень полезно для «раннего выхода» — когда мы хотим прекратить выполнение функции при определённом условии:
function divide(a, b) {
if (b === 0) {
return "Ошибка: деление на ноль!"; // ранний return — выходим сразу
}
// Эта строка выполнится только если b !== 0
return a / b;
}
console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // "Ошибка: деление на ноль!"
Без раннего return код был бы сложнее читать — пришлось бы вкладывать логику в else-блоки. Ранний return делает функции чище и понятнее.
// Без раннего return (хуже — глубокая вложенность)
function divide(a, b) {
if (b !== 0) {
return a / b;
} else {
return "Ошибка: деление на ноль!";
}
}
// С ранним return (лучше — плоский код)
function divide(a, b) {
if (b === 0) return "Ошибка: деление на ноль!";
return a / b;
}
🔑 return без значения (просто return;) тоже завершает функцию — но возвращает undefined. Это используется для раннего выхода из функций, которые ничего не возвращают.
❓ Функция без return возвращает undefined
Важный момент: любая функция в JavaScript что-то возвращает. Если вы не написали return — функция автоматически возвращает специальное значение undefined.
function sayHello() {
console.log("Привет!"); // функция что-то делает, но ничего не возвращает
}
let result = sayHello(); // Привет! — выведет в консоль
console.log(result); // undefined — функция вернула undefined
// Это может быть источником ошибок:
function double(n) {
let result = n * 2;
// Забыли написать return!
// return result; // <-- нужна эта строка
}
let x = double(5);
console.log(x); // undefined (не 10!)
console.log(x + 1); // NaN — потому что undefined + 1 = NaN
⚠️ Частая ошибка новичков: написать вычисление внутри функции, но забыть return. Функция посчитает всё правильно внутри, но результат «испарится» и наружу выйдет undefined.
Запомните: вызвать функцию и получить её значение — разные вещи:
function calculateArea(w, h) {
return w * h;
}
// "Вызвать функцию" — запустить код внутри
calculateArea(5, 3); // выполнилась, посчитала 15, но результат нигде не сохранён
// "Вернуть значение" — получить результат наружу
let area = calculateArea(5, 3); // теперь area = 15
// Или использовать прямо в выражении:
console.log(calculateArea(5, 3) * 2); // 30
🛠️ Полный пример: собираем всё вместе
Давайте напишем небольшую программу с несколькими функциями — расчёт стоимости заказа. Здесь будет и return, и ранний return, и использование результата одной функции в другой.
// Функция расчёта цены со скидкой
function applyDiscount(price, discountPercent) {
if (discountPercent < 0 || discountPercent > 100) {
return "Ошибка: некорректная скидка";
}
let discount = price * discountPercent / 100;
return price - discount;
}
// Функция расчёта итого с НДС
function calculateTotal(price, vatPercent) {
let vat = price * vatPercent / 100;
return price + vat;
}
// Функция форматирования цены
function formatPrice(amount) {
return amount.toFixed(2) + " ₽";
}
// Используем функции вместе:
let originalPrice = 1000;
let discountedPrice = applyDiscount(originalPrice, 10); // 900
let totalPrice = calculateTotal(discountedPrice, 20); // 1080
console.log("Итого к оплате:", formatPrice(totalPrice)); // "Итого к оплате: 1080.00 ₽"
Посмотрите, как каждая функция делает ровно одну вещь. Такой код легко читать, легко тестировать и легко изменять.
✅ Итоги урока
- Функции нужны для переиспользования кода и декомпозиции задачи на части
- Function Declaration —
function name() {}: можно вызвать до объявления (hoisting) - Function Expression —
const name = function() {};: нельзя вызвать до строки с присваиванием returnвозвращает значение из функции и немедленно прекращает её выполнение- Ранний
return— способ выйти из функции при нужном условии, делает код чище - Функция без
returnвозвращаетundefined— это частая причина ошибок - Важно понимать разницу: вызвать функцию и использовать её возвращаемое значение
В следующем уроке разберём параметры vs аргументы подробнее и научимся задавать значения по умолчанию. 🚀
Тест: Объявление функций и return
7 вопросов