← JavaScript/Стрелочные функции#64 из 383← ПредыдущийСледующий →+20 XP
Полезно по теме:Гайд: как учить JavaScriptПрактика: JS базаПрактика: async и сетьТермин: Closure

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

В любом реальном React или Vue проекте 80% функций написаны стрелочным синтаксисом. const handleClick = () => {}, .filter(item => item.active), .map(user => user.name) — всё это стрелочные функции. Это не просто сокращённый синтаксис — у них другое поведение this, что очень важно в объектах и классах.

На основе предыдущих уроков

Стрелочные функции — это сокращённый синтаксис Function Expression. Они используются как колбэки в методах массивов и везде где нужна компактная функция.

Синтаксис стрелочных функций

// Обычная Function Expression:
const add = function(a, b) { return a + b }

// Стрелочная эквивалентная запись:
const add = (a, b) => a + b

// Один параметр — скобки необязательны:
const double = x => x * 2

// Без параметров — пустые скобки обязательны:
const greet = () => 'Привет!'

// Несколько строк — нужны {} и явный return:
const process = (x) => {
  const doubled = x * 2
  return doubled + 1
}

Неявный return

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

const square = x => x * x          // неявный return
const isAdult = age => age >= 18   // неявный return, возвращает boolean
const greetUser = name => `Привет, ${name}!`  // возвращает строку

Возврат объекта — нужны скобки!

// Ошибка: JS думает что {} это тело функции
const getItem = id => { id, name: 'test' }  // вернёт undefined!

// Правильно: оборачиваем объектный литерал в ()
const getItem = id => ({ id, name: 'test' })  // вернёт объект

this в стрелочных функциях — главное отличие

Обычная функция имеет своё this — оно зависит от того как функция вызвана.

Стрелочная функция берёт `this` из внешней области — лексическое this.

const timer = {
  seconds: 0,
  start() {
    // Обычная функция — this потеряется в колбэке:
    // setInterval(function() { this.seconds++ }, 1000) // ошибка!

    // Стрелочная — this = timer:
    setInterval(() => {
      this.seconds++  // this = timer (из start())
      console.log(this.seconds)
    }, 1000)
  }
}

Ограничения стрелочных функций

Нельзя использовать как методы объекта (если нужен this):

const cart = {
  items: [],
  // Плохо — this будет undefined или window:
  add: (item) => { this.items.push(item) },
  // Хорошо — обычный метод:
  add(item) { this.items.push(item) },
}

Нельзя использовать как конструктор (с new):

const Person = (name) => { this.name = name }
new Person('Иван')  // TypeError: Person is not a constructor

Типичные ошибки

Ошибка 1: Забыть скобки вокруг возвращаемого объекта

const toUser = data => { id: data.id, name: data.name }  // undefined!
const toUser = data => ({ id: data.id, name: data.name }) // объект

Ошибка 2: Использовать стрелочную функцию как метод с this

const counter = {
  value: 0,
  increment: () => { this.value++ }  // this — не counter!
}
counter.increment()
console.log(counter.value)  // 0 — не изменилось

Ошибка 3: Вложенные стрелочные функции и читаемость

// Нечитаемо:
const result = a => b => c => a + b + c
// Разворачивай если сложно читать:
const add = (a) => (b) => (c) => a + b + c

В реальных проектах

Стрелочные функции — стандарт в современном JS. В React: const Component = () => <div/>, обработчики событий, хуки. В работе с данными: .map(), .filter(), .reduce() — везде стрелочные колбэки. Обычные функции остаются для методов объектов, конструкторов и когда нужен hoisting.

Примеры

Стрелочные функции в обработке данных заказов

const orders = [
  { id: 1, total: 2500, status: 'delivered', items: 3 },
  { id: 2, total: 750,  status: 'pending',   items: 1 },
  { id: 3, total: 8900, status: 'delivered', items: 5 },
  { id: 4, total: 150,  status: 'cancelled', items: 1 },
  { id: 5, total: 3200, status: 'delivered', items: 2 },
]

// Компактные стрелочные функции для трансформации
const isDelivered = o => o.status === 'delivered'
const getTotal = o => o.total
const sumReducer = (acc, val) => acc + val
const formatOrder = o => ({ id: o.id, amount: `${o.total} ₽`, items: o.items })

// Выручка от доставленных заказов
const deliveredRevenue = orders
  .filter(isDelivered)
  .map(getTotal)
  .reduce(sumReducer, 0)

console.log('Выручка:', deliveredRevenue)  // 14600

// Краткая сводка по доставленным
const summary = orders
  .filter(isDelivered)
  .map(formatOrder)

console.log(summary)
// [{ id: 1, amount: '2500 ₽', items: 3 }, ...]

// Возврат объекта стрелочной функцией
const toCartItem = product => ({
  productId: product.id,
  quantity: 1,
  price: product.price,
})
console.log(toCartItem({ id: 42, price: 1500 }))
// { productId: 42, quantity: 1, price: 1500 }

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

В любом реальном React или Vue проекте 80% функций написаны стрелочным синтаксисом. const handleClick = () => {}, .filter(item => item.active), .map(user => user.name) — всё это стрелочные функции. Это не просто сокращённый синтаксис — у них другое поведение this, что очень важно в объектах и классах.

На основе предыдущих уроков

Стрелочные функции — это сокращённый синтаксис Function Expression. Они используются как колбэки в методах массивов и везде где нужна компактная функция.

Синтаксис стрелочных функций

// Обычная Function Expression:
const add = function(a, b) { return a + b }

// Стрелочная эквивалентная запись:
const add = (a, b) => a + b

// Один параметр — скобки необязательны:
const double = x => x * 2

// Без параметров — пустые скобки обязательны:
const greet = () => 'Привет!'

// Несколько строк — нужны {} и явный return:
const process = (x) => {
  const doubled = x * 2
  return doubled + 1
}

Неявный return

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

const square = x => x * x          // неявный return
const isAdult = age => age >= 18   // неявный return, возвращает boolean
const greetUser = name => `Привет, ${name}!`  // возвращает строку

Возврат объекта — нужны скобки!

// Ошибка: JS думает что {} это тело функции
const getItem = id => { id, name: 'test' }  // вернёт undefined!

// Правильно: оборачиваем объектный литерал в ()
const getItem = id => ({ id, name: 'test' })  // вернёт объект

this в стрелочных функциях — главное отличие

Обычная функция имеет своё this — оно зависит от того как функция вызвана.

Стрелочная функция берёт `this` из внешней области — лексическое this.

const timer = {
  seconds: 0,
  start() {
    // Обычная функция — this потеряется в колбэке:
    // setInterval(function() { this.seconds++ }, 1000) // ошибка!

    // Стрелочная — this = timer:
    setInterval(() => {
      this.seconds++  // this = timer (из start())
      console.log(this.seconds)
    }, 1000)
  }
}

Ограничения стрелочных функций

Нельзя использовать как методы объекта (если нужен this):

const cart = {
  items: [],
  // Плохо — this будет undefined или window:
  add: (item) => { this.items.push(item) },
  // Хорошо — обычный метод:
  add(item) { this.items.push(item) },
}

Нельзя использовать как конструктор (с new):

const Person = (name) => { this.name = name }
new Person('Иван')  // TypeError: Person is not a constructor

Типичные ошибки

Ошибка 1: Забыть скобки вокруг возвращаемого объекта

const toUser = data => { id: data.id, name: data.name }  // undefined!
const toUser = data => ({ id: data.id, name: data.name }) // объект

Ошибка 2: Использовать стрелочную функцию как метод с this

const counter = {
  value: 0,
  increment: () => { this.value++ }  // this — не counter!
}
counter.increment()
console.log(counter.value)  // 0 — не изменилось

Ошибка 3: Вложенные стрелочные функции и читаемость

// Нечитаемо:
const result = a => b => c => a + b + c
// Разворачивай если сложно читать:
const add = (a) => (b) => (c) => a + b + c

В реальных проектах

Стрелочные функции — стандарт в современном JS. В React: const Component = () => <div/>, обработчики событий, хуки. В работе с данными: .map(), .filter(), .reduce() — везде стрелочные колбэки. Обычные функции остаются для методов объектов, конструкторов и когда нужен hoisting.

Примеры

Стрелочные функции в обработке данных заказов

const orders = [
  { id: 1, total: 2500, status: 'delivered', items: 3 },
  { id: 2, total: 750,  status: 'pending',   items: 1 },
  { id: 3, total: 8900, status: 'delivered', items: 5 },
  { id: 4, total: 150,  status: 'cancelled', items: 1 },
  { id: 5, total: 3200, status: 'delivered', items: 2 },
]

// Компактные стрелочные функции для трансформации
const isDelivered = o => o.status === 'delivered'
const getTotal = o => o.total
const sumReducer = (acc, val) => acc + val
const formatOrder = o => ({ id: o.id, amount: `${o.total} ₽`, items: o.items })

// Выручка от доставленных заказов
const deliveredRevenue = orders
  .filter(isDelivered)
  .map(getTotal)
  .reduce(sumReducer, 0)

console.log('Выручка:', deliveredRevenue)  // 14600

// Краткая сводка по доставленным
const summary = orders
  .filter(isDelivered)
  .map(formatOrder)

console.log(summary)
// [{ id: 1, amount: '2500 ₽', items: 3 }, ...]

// Возврат объекта стрелочной функцией
const toCartItem = product => ({
  productId: product.id,
  quantity: 1,
  price: product.price,
})
console.log(toCartItem({ id: 42, price: 1500 }))
// { productId: 42, quantity: 1, price: 1500 }

Задание

Перепиши функции через стрелочный синтаксис. isAdult принимает возраст и возвращает boolean. formatFullName принимает имя и фамилию и возвращает строку "Фамилия И." getIds принимает массив объектов с полем id и возвращает массив id.

Подсказка

isAdult = age => age >= 18. formatFullName = (firstName, lastName) => lastName + " " + firstName[0] + ".". getIds = items => items.map(item => item.id)

Загружаем среду выполнения...
Загружаем AI-помощника...