> В чем разница 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'; };
// Стрелочная функция - нет собственного this
const 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 внешней функции, а не создаёт свой.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью