> В чем разница function declaration, function expression и стрелочной функции в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Язык: JavaScript · Категория: Технические вопросы
Компании: Mosline
Стек: Node.js, JavaScript
> Пример ответа
Короткий ответ
Function declaration (function foo() {}) - объявление, которое hoistится целиком, доступно до определения в блоке. Function expression (const foo = function() {}) - не hoistится, присваивается переменной, может быть анонимным. Стрелочная функция (() => {}) - не имеет собственного this, arguments, не может быть конструктором, не hoistится. Основные различия: hoisting, контекст this, синтаксис и область видимости.
Подробное объяснение
Function declaration (FD) создаётся до выполнения кода в своей области видимости благодаря hoisting - интерпретатор поднимает объявление целиком. Это позволяет вызывать функцию до её строки в коде. FD привязана к блоку (в strict mode - к функции или глобально). Имеет собственный this и arguments.
Function expression (FE) - функция, присвоенная переменной. Hoisting переменной (var) или отсутствие hoisting (let/const) означает, что функция недоступна до строки инициализации. FE может быть именованной (для рекурсии) или анонимной. Имеет собственный this и arguments.
Стрелочная функция - синтаксический сахар для коротких функций. Ключевое отличие: она не создаёт собственный this, а наследует его из внешнего лексического окружения. Аналогично с arguments - доступ к arguments внешней функции. Не может использоваться как конструктор (new выбросит TypeError). Не имеет свойства prototype. Не поддерживает yield (не может быть генератором).
На практике
Для обработчиков событий в классах React или колбэков в Node.js (например, в Promise или async/await) стрелочные функции удобны, так как сохраняют контекст. Для методов объекта или конструкторов используйте FD или FE, чтобы получить собственный this. FD предпочтительна для рекурсивных вызовов и читаемости кода, так как hoisting позволяет размещать вызовы до определения. FE полезна для колбэков, передаваемых по ссылке, или для условного создания функций.
Пример кода
JAVASCRIPT// Function declaration - hoisting работаетconsole.log(foo()); // 'foo'function foo() { return 'foo'; }// Function expression - ошибка до инициализацииconsole.log(bar); // ReferenceError (let) или undefined (var)const bar = function() { return 'bar'; };// Стрелочная функция - нет собственного thisconst obj = {name: 'test',regular: function() { console.log(this.name); },arrow: () => { console.log(this.name); }};obj.regular(); // 'test'obj.arrow(); // undefined (this - глобальный объект)// Стрелочная функция не может быть конструкторомconst Arrow = () => {};new Arrow(); // TypeError: Arrow is not a constructor
Как отвечать на собеседовании
Начни с краткого определения каждого типа, затем перечисли ключевые различия: hoisting, this, arguments, использование с new. Приведи примеры, где каждый тип уместен. Для senior-уровня добавь нюансы: поведение в strict mode, разница между var и let/const в FE, влияние на производительность (стрелочные функции не имеют prototype). Упомяни, что стрелочные функции не могут быть методами объекта, если нужен доступ к this объекта. Избегай излишней детализации про event loop - это не относится к вопросу.
Что проверяет интервьюер
Глубину понимания механизмов JavaScript: hoisting, лексическое окружение, контекст выполнения. Умение выбирать правильный тип функции под задачу. Понимание ограничений стрелочных функций (отсутствие arguments, конструктора). Для senior - способность объяснить, как это влияет на архитектуру кода, например, в классах или колбэках.
Типичные ошибки
- Утверждение, что стрелочные функции не имеют this вообще (на самом деле наследуют из внешнего контекста).
- Путаница с hoisting: думать, что FE тоже hoistится (hoistится только переменная, не значение).
- Использование стрелочных функций как методов объекта, теряя контекст.
- Попытка вызвать стрелочную функцию с new.
- Забывают, что arguments в стрелочной функции ссылается на arguments внешней функции, а не создаёт свой.
> Похожие задачи по JavaScript
Какой сборщик используете
Писали ли вы тесты
Для чего нужен тип Symbol в JavaScript?
Приходилось ли писать Docker файлы и работать с контейнерами
> Похожие задачи по frontend
Писали ли вы тесты
Расскажите про свой профессиональный путь
Для чего нужен тип Symbol в JavaScript?
Приходилось ли писать Docker файлы и работать с контейнерами
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью