Глиф Учебники

Урок 6. Функции и стрелочные функции

Курс «JavaScript» · урок 6 из 10 · 4 минуты чтения

Функция — именованный кусок кода, который можно вызывать сколько угодно раз. Функции избавляют от повторов: код пишется один раз, а используется везде, где нужен. Вы уже пользовались готовыми функциями: console.log, Number, Math.trunc. В этом уроке — свои.

Объявление и вызов

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

console.log(greet("Аня"));
console.log(greet("Олег"));
Вывод
Привет, Аня!
Привет, Олег!
вызов console.log(greet("Аня")); "Привет, Аня!" встаёт на место вызова функция function greet(name) { name "Аня" параметр return "Привет, " + name + "!"; = "Привет, Аня!" } аргумент return
При вызове greet("Аня") аргумент "Аня" попадает в параметр name, функция собирает строку, и return возвращает "Привет, Аня!" — это значение встаёт на место вызова в console.log.

Скобки при вызове обязательны. greet без скобок — это сама функция, а не её результат.

Имена функциям дают по действию, обычно глаголом: calcTotal, showMessage, isValid. По имени должно быть понятно, что функция делает, — тогда код читается без комментариев.

Функция без return

Если return нет или он стоит без значения, функция возвращает undefined. Такие функции нужны ради действия — вывести, сохранить, изменить страницу, — а не ради результата.

JavaScript
function printLine(text) {
  console.log("-- " + text + " --");
}

const result = printLine("раздел");
console.log(result);
Вывод
-- раздел --
undefined

Несколько параметров и значения по умолчанию

Параметров может быть сколько угодно, через запятую. Если при вызове аргумент не передан, параметр получает undefined. Значение по умолчанию задаётся прямо в объявлении:

JavaScript
function power(base, exponent = 2) {
  return base ** exponent;
}

console.log(power(5));
console.log(power(2, 10));
Вывод
25
1024

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

Если число аргументов заранее неизвестно, параметр с тремя точками собирает все переданные значения в массив:

JavaScript
function total(...numbers) {
  let sum = 0;
  for (const n of numbers) {
    sum += n;
  }
  return sum;
}

console.log(total(1, 2, 3));
console.log(total(10, 20, 30, 40));
Вывод
6
100

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

Переменная, объявленная внутри функции, видна только в этой функции. Снаружи её нет, а одноимённая переменная снаружи — это другая переменная:

JavaScript
let message = "снаружи";

function show() {
  let message = "внутри";
  console.log(message);
}

show();
console.log(message);
Вывод
внутри
снаружи

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

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

В JavaScript функция — такое же значение, как число или строка. Её можно положить в переменную:

JavaScript
const square = function (x) {
  return x * x;
};

console.log(square(7));
Вывод
49

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

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

Короткая запись функции — стрелочная функция (arrow function), со знаком =>:

JavaScript
const square = (x) => x * x;
const sum = (a, b) => a + b;
const hello = () => console.log("Привет");

console.log(square(4));
console.log(sum(2, 3));
hello();
Вывод
16
5
Привет
JavaScript
const describe = (n) => {
  const kind = n % 2 === 0 ? "чётное" : "нечётное";
  return `${n} — ${kind}`;
};

console.log(describe(7));
Вывод
7 — нечётное
стрелка const square = (x) => x * x; параметры результат — без return вызов с аргументами 2 и 3: (a, b) => a + b 5 возвращается само (a, b) => { a + b } undefined скобки без return (a, b) => { return a + b; } 5 скобки и return
В стрелочной функции параметры стоят перед =>, а значение одного выражения после стрелки возвращается само; с фигурными скобками нужен return, иначе вызов даёт undefined.

Чтобы стрелочная функция вернула объект, его берут в круглые скобки: () => ({ ok: true }). Без них фигурные скобки считаются телом функции.

У стрелочных функций нет своего this (о нём — в уроке Объекты и JSON), поэтому методы объектов пишут обычными функциями. Для коротких действий — обработки элементов массива, таймеров, событий — стрелочные функции удобнее.

Функции обратного вызова

Раз функция — значение, её можно передать другой функции как аргумент. Такую функцию называют функцией обратного вызова (callback, колбэк): её вызовут потом, когда придёт время.

JavaScript
function repeat(times, action) {
  for (let i = 1; i <= times; i++) {
    action(i);
  }
}

repeat(3, (n) => console.log("Повтор " + n));
Вывод
Повтор 1
Повтор 2
Повтор 3
repeat(3, (n) => console.log("Повтор " + n)); функция — как значение function repeat(times, action) { for (let i = 1; i <= times; i++) { action(i); } } три вызова колбэка n = 1 Повтор 1 n = 2 Повтор 2 n = 3 Повтор 3
Стрелочная функция передаётся в repeat как значение и попадает в параметр action, а цикл внутри repeat сам вызывает её три раза — с n = 1, 2 и 3.

repeat не знает, что именно нужно сделать, — она лишь вызывает переданную функцию нужное число раз. На этом приёме построены методы массивов (map, filter), обработчики событий на странице и таймеры: в каждый из них передаётся функция.

Частые ошибки

Коротко

Проверьте себя

1. Что вернёт функция, в которой нет return?
2. Что выведет программа?
JavaScript
const add = (a, b) => {
  a + b;
};
console.log(add(2, 3));
3. Что выведет console.log(power(3)), если function power(x, n = 2) { return x ** n; }?
4. Что такое функция обратного вызова (callback)?