> В чем разница function declaration, function expression и стрелочной функции в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Kvando Technologies, Soft_Media_Group, РСХБ, Домклик, IT-One, Софт Медиа Групп, Сбер, TYMY, 1221 Systems, SmartWay
Стек: JavaScript
> Пример ответа
Короткий ответ
Основные различия: function declaration (FD) поднимается целиком и доступна до объявления, function expression (FE) - только после присвоения, стрелочная функция не имеет собственного this, arguments и не может быть использована как конструктор. Стрелочные функции не поднимаются и всегда анонимны. FD обязательно требует имени, FE может быть анонимным или именованным.
Подробное объяснение
Function declaration объявляется с ключевым словом function и именем. Она полностью hoistится - и объявление, и тело функции перемещаются в начало области видимости. Поэтому её можно вызывать до строки объявления. FD создаёт собственную привязку this и имеет объект arguments.
Function expression - это присвоение функции переменной. Функция может быть анонимной или именованной. Hoisting работает только для переменной (если используется var - undefined, если let/const - Temporal Dead Zone). До строки присвоения функция недоступна. Имеет собственный this и arguments.
Стрелочная функция - синтаксический сахар для коротких функций. Ключевые отличия:
- Не имеет собственного
this- берёт его из лексического окружения (внешней функции) - Не имеет объекта
arguments- использует rest parameters (...args) - Не может быть конструктором (вызов с
newвыбросит ошибку) - Не имеет свойства
prototype - Не может быть использована как generator (нет
yield) - Всегда анонимна (но можно присвоить переменной для отладки)
Дополнительно: стрелочные функции не поднимаются, ведут себя как FE с let/const. Их this фиксируется при создании и не может быть изменён через call, apply или bind.
На практике
Для обработчиков событий в классах React или методах объектов, где нужен доступ к this внешнего контекста, стрелочные функции - стандартный выбор. Если функция должна быть вызвана до объявления (например, для рекурсии или организации кода сверху вниз) - используйте FD. Когда нужно динамическое связывание this или доступ к arguments - FE или FD.
В современном коде стрелочные функции доминируют для колбэков, методов массивов (map, filter, reduce) и простых функций без собственного контекста. FD остаётся для объявления основных функций модуля или рекурсивных алгоритмов.
Пример кода
JAVASCRIPT// Function declaration - доступна до объявленияconsole.log(sum(2, 3)); // 5function sum(a, b) { return a + b; }// Function expression - только после присвоения// console.log(multiply(2, 3)); // ReferenceErrorconst multiply = function(a, b) { return a * b; };console.log(multiply(2, 3)); // 6// Стрелочная функция - нет собственного thisconst obj = {name: 'test',regular: function() { console.log(this.name); },arrow: () => { console.log(this.name); }};obj.regular(); // 'test'obj.arrow(); // undefined (this = глобальный объект)// Нет argumentsconst logArgs = (...args) => { console.log(args); };logArgs(1, 2, 3); // [1, 2, 3]// Нельзя использовать как конструктор// const instance = new (() => {}); // TypeError
Как отвечать на собеседовании
Начните с ключевых различий: hoisting, this, arguments, возможность быть конструктором. Затем приведите примеры, когда какой тип уместен. Для senior важно показать понимание лексического окружения и области видимости. Упомяните, что стрелочные функции не имеют собственного this и не могут быть перепривязаны - это и преимущество, и ограничение. Сравните поведение в методах объектов и классах. Если спросят про производительность - скажите, что разница минимальна, но стрелочные функции создают меньше замыканий при оптимизации.
Что проверяет интервьюер
Глубину понимания hoisting, области видимости, контекста выполнения и механизма this. Проверяется знание тонкостей: Temporal Dead Zone для FE с let/const, различие между именованным и анонимным FE, невозможность переопределить this у стрелочной функции. Также оценивается способность выбрать правильный тип функции под задачу и объяснить trade-off.
Типичные ошибки
- Утверждение, что стрелочные функции не hoistятся вообще - на самом деле они подчиняются правилам переменных (TDZ для
let/const) - Использование стрелочной функции как метода объекта, когда нужен
thisобъекта - Попытка вызвать
newна стрелочной функции или использоватьyield - Путаница между именованным FE и FD - именованный FE виден только внутри самой функции (для рекурсии)
- Забывают, что
argumentsв стрелочной функции ссылается на внешнюю функцию, если она есть
> Похожие задачи по frontend
Каковы преимущества optional chaining в JavaScript?
Зачем нужен async/await в JavaScript
Расскажите про асинхронность в JavaScript и средства работы с асинхронным кодом
Как избежать ошибки при обращении к свойству объекта, если объект undefined?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью