webroad.online
  1. 1Веб
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Инструменты
  8. 8React
  9. 9Стейт-менеджмент
  10. 10Next.js
  11. 11Формы
  12. 12Данные и бэкенд
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Анимации
  16. 16Тестирование
  17. 17Архитектура
JavaScript · Урок 3 из 17

Функции и замыкания

Стрелочные функции, параметры, функции как значения, замыкания.

Обновлено

Что такое функция

Функция — это именованный блок кода, который вы пишете один раз и запускаете сколько угодно раз. Она получает данные (параметры), что-то с ними делает и, при необходимости, возвращает результат (return).

Представьте рецепт: рецепт (функция) написан один раз; каждый раз, когда вы готовите (вызываете функцию), можно взять другие ингредиенты (аргументы).

function add(a, b) {   // a, b = параметры (нужные ингредиенты)
  return a + b         // результат
}

add(2, 3)              // 5  — 2 и 3 = аргументы (конкретные ингредиенты)
add(10, 20)            // 30

Два разных момента, которые важно различать:

Определение Вызов
Код function add(a, b) { ... } add(2, 3)
Что происходит JS запоминает рецепт, но не выполняет его JS выполняет тело функции
Сколько раз один сколько угодно

Зачем нужны функции

  • Повторное использование — не нужно копировать один и тот же код в 10 мест.
  • Имя — calculateTotal(cart) говорит, что делает; 15 строк вычислений — нет.
  • Изоляция — переменные внутри функции не смешиваются с остальным кодом.
  • Тестирование — маленькую функцию с понятным входом и выходом легко проверить.

Параметры и return

function greet(name = 'аноним') {   // значение по умолчанию
  return `Привет, ${name}`
}

greet()          // 'Привет, аноним'
greet('Ana')     // 'Привет, Ana'
  • return останавливает функцию и отдаёт результат. Всё после него не выполняется.
  • Без return функция возвращает undefined.
  • Отсутствующие параметры равны undefined (если у них нет значения по умолчанию).

Rest-параметры и деструктуризация

const total = (...nums) => nums.reduce((s, n) => s + n, 0)   // сколько угодно аргументов → массив
total(1, 2, 3)   // 6

function createUser({ name, role = 'user' }) {                 // получаете объект, достаёте поля
  return { name, role }
}
createUser({ name: 'Ana' })

Больше 3 параметров? Переходите на один объект — порядок больше не важен, а вызов читается сам.

Виды функций

1. Function declaration

function sum(a, b) {
  return a + b
}

2. Function expression

const sum = function (a, b) {
  return a + b
}

3. Стрелочная функция

const sum = (a, b) => a + b          // неявный return, одно выражение
const square = x => x * x            // один параметр — без скобок
const getUser = () => ({ id: 1 })    // возвращаете объект — нужны скобки
const log = msg => {                 // несколько строк — фигурные скобки + явный return
  console.log(msg)
}

4. Метод (функция внутри объекта или класса)

const cart = {
  items: [],
  add(item) { this.items.push(item) },
}

5. Асинхронная функция

async function loadUser(id) {
  const res = await fetch(`/api/users/${id}`)
  return res.json()
}

Всегда возвращает Promise — см. Async.

Различия, которые важны

Declaration Expression Стрелочная Метод
Hoisting — можно вызвать до строки, где она написана да нет нет —
Собственный this да (зависит от вызова) да нет — берёт this снаружи да = объект
arguments да да нет да
Можно вызвать с new да да нет нет
Неявный return нет нет да (одно выражение) нет

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

Ситуация Выбор
главная функция модуля, утилита, React-компонент declaration (function Card() {}) — читается понятно, есть hoisting
колбэки: map, filter, onClick, setTimeout, then стрелочная — коротко и сохраняет внешний this
маленькие функции в переменных, передаваемые как значения стрелочная
поведение объекта / класса, использующее this метод
всё, что работает с await async (в любой форме)
классический function expression сегодня редко — его заменили стрелочные

Функции — это значения

В JS функции — объекты первого класса: их можно класть в переменные, передавать аргументами, возвращать из других функций.

const shout = text => text.toUpperCase()
['a', 'b'].map(shout)          // передана аргументом → ['A', 'B']

const multiplier = factor => x => x * factor   // возвращает функцию
const double = multiplier(2)
double(5)                      // 10

Функция, которая принимает или возвращает функции, называется функцией высшего порядка (map, filter, addEventListener).

Замыкание

Функция помнит переменные того места, где она была создана, даже после того, как это место «закончилось». Это и есть замыкание (closure).

function createCounter() {
  let n = 0                // продолжает жить, «замкнутая» в возвращённой функции
  return () => ++n
}

const next = createCounter()
next()   // 1
next()   // 2 — n запомнилась

const other = createCounter()
other()  // 1 — каждый вызов создаёт новую n

На замыканиях построены useState, обработчики событий в React, debounce, модули.

Чистые функции

Функция чистая, если:

  1. при одинаковом входе она всегда даёт одинаковый результат;
  2. у неё нет побочных эффектов (не меняет внешние переменные, не делает запросов, не пишет в DOM).
const withVat = price => price * 1.2           // ✓ чистая

let total = 0
const addToTotal = price => { total += price } // ✗ меняет что-то снаружи

React-компоненты должны быть чистыми. Бизнес-логика — тоже: её тривиально тестировать.

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

  • Забыли return (особенно в функциях с фигурными скобками) → undefined.
  • Стрелочная функция возвращает объект без скобок: () => { id: 1 } возвращает undefined.
  • Вызов вместо передачи: onClick={save()} выполняется сразу; правильно onClick={save} или onClick={() => save(id)}.

Коротко

  • Функция = именованный код, определяется один раз, вызывается сколько угодно; параметры → return.
  • Declaration — для главных функций, стрелочные — для колбэков, методы — для объектов.
  • Функции — это значения; замыкание = функция помнит, где была создана.

Официальные источники

Упражнения

Была ли страница полезной?

Один клик — без регистрации.