Gernar
JavaScript: язык и типы

В чем разница между стрелочной функцией и обычной функцией в JavaScript

Разбор вопроса «В чем разница между стрелочной функцией и обычной функцией в JavaScript» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.

Вопрос

В чем разница между стрелочной функцией и обычной функцией в JavaScript

Профессия

Frontend Developer

Что хочет услышать интервьюер

Интервьюер хочет убедиться, что кандидат понимает ключевые различия между стрелочными и обычными функциями, включая контекст this, наличие arguments, возможность использования в качестве конструктора и синтаксические особенности. Также важно показать, что кандидат знает, когда и зачем использовать каждый тип функций.

Ключевые тезисы

  • Стрелочные функции не имеют своего контекста (this), он берется из окружающего лексического окружения, тогда как у обычных функций this определяется в момент вызова.
  • У стрелочных функций нет объекта arguments, в отличие от обычных функций, где он доступен по умолчанию.
  • Стрелочные функции нельзя использовать как конструктор (с оператором new), а обычные функции — можно.
  • Синтаксис стрелочных функций короче и удобнее для простых операций и колбэков.

Подробный ответ

Основное отличие стрелочных функций от обычных заключается в работе с контекстом this. В обычных функциях this определяется в момент вызова и зависит от того, как была вызвана функция (например, через new, как метод объекта или просто как функция). Стрелочные функции не имеют своего this, а берут его из окружающего лексического контекста. Это делает их удобными для использования в колбэках, где важно сохранить контекст. Еще одно важное отличие — отсутствие объекта arguments в стрелочных функциях. В обычных функциях arguments содержит все переданные аргументы, даже если они не объявлены в параметрах. В стрелочных функциях для этого нужно использовать rest-параметры (...args). Также стрелочные функции нельзя использовать как конструкторы с оператором new, так как у них нет свойства prototype. Синтаксис стрелочных функций короче, что делает их удобными для простых операций и колбэков, особенно в методах массивов (map, filter и т.д.).

Практические примеры

Пример 1

Пример с контекстом this:

const obj = {
  value: 'test',
  regularFunc: function() { console.log(this.value); },
  arrowFunc: () => { console.log(this.value); }
};
obj.regularFunc(); // 'test'
obj.arrowFunc(); // undefined (берет this из внешнего контекста)

Пример 2

Пример с arguments:

function regular() { console.log(arguments); }
const arrow = (...args) => { console.log(args); };
regular(1, 2, 3); // Arguments(3) [1, 2, 3]
arrow(1, 2, 3); // [1, 2, 3]

Пример 3

Пример с конструктором:

function Regular() {}
const Arrow = () => {};
new Regular(); // работает
new Arrow(); // TypeError: Arrow is not a constructor

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

  • Использование стрелочных функций как методов объекта, когда нужно обращаться к this объекта
  • Попытка использовать arguments в стрелочной функции без rest-параметров
  • Попытка вызвать стрелочную функцию с new

Связанные темы

  • Лексическое окружение (Lexical Environment)
  • Прототипное наследование в JavaScript
  • Rest и spread операторы
  • Методы массивов (map, filter, reduce)

Follow-up вопросы

Можете привести пример, где использование стрелочной функции приведет к ошибке из-за контекста this?

Уровень: basic

Пример: метод объекта, использующий this. В стрелочной функции this будет ссылаться на внешний контекст (например, window), а не на сам объект. В обычной функции this корректно указывает на объект.

Как можно получить доступ к аргументам функции в стрелочной функции, если у нее нет объекта arguments?

Уровень: intermediate

В стрелочной функции можно использовать rest-параметры (...args), чтобы получить все переданные аргументы в виде массива. Например: const func = (...args) => console.log(args);

Почему стрелочные функции нельзя использовать как конструктор с оператором new?

Уровень: intermediate

Стрелочные функции не имеют собственного контекста this и свойства prototype, которое необходимо для работы оператора new. При попытке вызвать new с стрелочной функцией возникнет ошибка.

Как поведение стрелочных функций влияет на их использование в качестве обработчиков событий в React?

Уровень: advanced

В React стрелочные функции удобны для обработчиков, так как сохраняют контекст компонента (this). Обычные функции требуют явного привязывания контекста (bind) или использования конструктора.

Есть ли различия в поднятии (hoisting) между стрелочными и обычными функциями?

Уровень: intermediate

Да. Обычные функции (function declaration) поднимаются полностью, их можно вызвать до объявления. Стрелочные функции (как и function expression) не поднимаются — попытка вызова до объявления приведет к ошибке.

Содержание