Функции в JavaScript #
Функция — именованный или анонимный блок кода, который можно вызвать повторно с разными аргументами. В JavaScript функции — это значения: их можно передавать, возвращать и хранить в переменных.
Function Declaration #
Самый прямой способ — объявить функцию ключевым словом function:
function formatPrice(amount, currency = 'RUB') {
return `${amount.toFixed(2)} ${currency}`
}
formatPrice(1490) // "1490.00 RUB"
formatPrice(12.5, 'EUR') // "12.50 EUR"
Объявления «поднимаются» (hoisting): вызов до строки с function в том же scope обычно работает. На практике объявляйте функции до использования — код читается проще.
Параметры и аргументы #
- Параметры — имена во скобках при объявлении (
amount,currency). - Аргументы — значения при вызове (
1490,'EUR').
Лишние аргументы игнорируются. Недостающие без значения по умолчанию дают undefined:
function buildQuery(path, page) {
return `${path}?page=${page}`
}
buildQuery('/catalog') // "/catalog?page=undefined"
Значения по умолчанию и rest-параметры снимают такие сюрпризы:
function buildQuery(path, page = 1, ...filters) {
const base = `${path}?page=${page}`
if (filters.length === 0) return base
return `${base}&filter=${filters.join(',')}`
}
buildQuery('/catalog', 2, 'sale', 'new')
// "/catalog?page=2&filter=sale,new"
return и побочные эффекты #
return завершает выполнение и отдаёт результат наружу. Без return функция возвращает undefined.
function calcDiscount(total, percent) {
if (percent < 0 || percent > 100) {
return null // ранний выход при некорректных данных
}
return total - (total * percent) / 100
}
const paid = calcDiscount(2000, 15) // 1700
Разделяйте вычисление (чистая функция с return) и побочный эффект (запись в DOM, console.log, запрос к сети). Так проще тестировать и переиспользовать код.
Function Expression #
Функцию можно присвоить переменной — это выражение, не объявление:
const summarizeCart = function (items) {
return items.reduce((sum, item) => sum + item.price, 0)
}
summarizeCart([
{ title: 'JSFlow Sticker', price: 150 },
{ title: 'Notebook', price: 490 },
]) // 640
У function expression нет hoisting как у declaration: переменная существует, но до присваивания её нельзя вызвать.
Стрелочные функции #
Короткий синтаксис ES2015. Удобны для колбэков и однострочных преобразований:
const toSlug = (title) => title.trim().toLowerCase().replace(/\s+/g, '-')
const scores = [88, 91, 74]
const passed = scores.filter((score) => score >= 80) // [88, 91]
Особенности стрелок:
| Тема | Поведение |
|---|---|
this | Берётся из внешней области (лексический this) |
arguments | Нет собственного объекта arguments |
new | Нельзя вызвать как конструктор |
| тело | Одно выражение — неявный return; блок { } — нужен явный return |
const double = (n) => n * 2
const describe = (n) => {
return `value=${n}`
}
Для методов объекта с this чаще берут обычную function или метод в литерале — стрелка «приклеит» чужой this.
Функция как значение #
Функции передают в другие функции (колбэки) и возвращают из функций:
function createTaxed(rate) {
return function applyTax(net) {
return net * (1 + rate)
}
}
const withVat = createTaxed(0.2)
withVat(1000) // 1200
Это основа замыканий, событий и асинхронного кода — отдельные уроки в следующих разделах.
Частые ошибки #
- Забыли
return— получилиundefinedвместо результата. - Сравнение с
=вместо===внутри условия. - Стрелка как метод объекта — неожиданный
this. - Мутация аргументов-объектов без документации — вызывающий код ломается неочевидно.
// плохо: тихо меняем входной объект
function markDone(task) {
task.done = true
}
// лучше: вернуть новый объект
function markDone(task) {
return { ...task, done: true }
}
Итог #
- Функция переиспользует логику с параметрами и
return. - Declaration, expression и стрелки — разные формы одной идеи; выбирайте по контексту.
- Чистые функции проще сопровождать, чем смесь расчёта и побочных эффектов.
- Стрелки удобны в колбэках; для методов с
this— обычные функции.