Функции
Основы функций — функции первого класса и высшего порядка, замыкания, привязка this, стрелочные функции и call/apply/bind.
10 вопросов
JuniorТеорияОчень частоЧем стрелочные функции отличаются от обычных функций?
Чем стрелочные функции отличаются от обычных функций?
Стрелочные функции дают краткий синтаксис => и, что важно, не имеют собственных this, arguments, super и new.target — они наследуют this лексически из окружающей области видимости. Их также нельзя использовать как конструкторы с new, и у них нет prototype, поэтому они подходят для колбэков, но не для методов объекта, которым нужен свой this.
Типичные ошибки
- ✗Считать, что стрелочная функция динамически привязывает собственный
this, как обычная функция - ✗Пытаться использовать стрелочную функцию как конструктор с
newили ждать объектarguments
Уточняющие вопросы
- →Почему стрелка, использованная как метод объекта, часто выводит
undefinedдляthis? - →Как получить переменное число аргументов внутри стрелочной функции без
arguments?
MiddleТеорияОчень частоЧто такое замыкание в JavaScript?
Что такое замыкание в JavaScript?
Замыкание — это функция в связке с лексическим окружением, в котором она была создана, поэтому она сохраняет доступ к переменным той области видимости даже после того, как внешняя функция завершилась. Это позволяет внутренней функции читать и обновлять внешние переменные, что лежит в основе приватного состояния, фабрик функций и колбэков с состоянием.
Типичные ошибки
- ✗Думать, что замыкание копирует внешние переменные, а не держит на них живую ссылку
- ✗Считать, что переменные становятся недоступны, как только внешняя функция возвращается
Уточняющие вопросы
- →Как замыкания позволяют реализовать приватный счётчик без открытой переменной?
- →Делят ли два замыкания из одного вызова общие переменные или получают отдельные копии?
JuniorТеорияЧастоЧто значит, что функции в JavaScript — объекты первого класса?
Что значит, что функции в JavaScript — объекты первого класса?
Функции — это значения, как и любые другие: их можно присвоить переменной, передать как аргумент, вернуть из другой функции и хранить в массиве или объекте. Именно это даёт колбэки, функции высшего порядка и обработчики событий вроде addEventListener('click', handler).
Типичные ошибки
- ✗Думать, что первый класс — про приоритет выполнения или всплытие, а не про то, что функции являются значениями
- ✗Считать, что функции нельзя возвращать из других функций или хранить в структурах данных
Уточняющие вопросы
- →Как поддержка функций первого класса делает возможными функции высшего порядка?
- →В чём разница между передачей
handlerиhandler()вaddEventListener?
MiddleТеорияЧастоВ чём разница между call, apply и bind?
В чём разница между call, apply и bind?
Все три задают this функции указанному объекту. call вызывает её сразу с аргументами, перечисленными по отдельности; apply вызывает её сразу, но принимает аргументы единым массивом; bind не вызывает — он возвращает новую функцию с навсегда зафиксированным this (и ведущими аргументами), чтобы вызвать её позже.
Типичные ошибки
- ✗Думать, что
bindвызывает функцию сразу, а не возвращает новую - ✗Путать
callиapply—applyпринимает массив,callпринимает список
Уточняющие вопросы
- →Как
bindобеспечивает частичное применение, заранее фиксируя ведущие аргументы? - →Как реализовать собственный
bindс помощьюapply?
MiddleТеорияЧастоЧто такое функция высшего порядка?
Что такое функция высшего порядка?
Функция высшего порядка принимает одну или несколько функций как аргументы, возвращает функцию или делает и то, и другое. Она опирается на то, что функции — значения первого класса. Методы массива map, filter и reduce — встроенные примеры, принимающие колбэк, а фабрика функций, возвращающая настроенную функцию, — это случай с возвратом.
Типичные ошибки
- ✗Путать функции высшего порядка с рекурсивными или вложенными функциями
- ✗Думать, что подходят только функции, принимающие колбэк, забывая о случае с возвратом функции
Уточняющие вопросы
- →Почему
mapсчитается функцией высшего порядка, а обычный циклfor— нет? - →Как фабрика функций демонстрирует случай возврата функции?
MiddleТеорияЧастоКак this разрешается для метода, обычного вызова и стрелки?
Как this разрешается для метода, обычного вызова и стрелки?
this определяется тем, как функция вызвана, а не где определена. При вызове obj.method() this равен obj (неявная привязка). При обычном вызове this — глобальный объект в нестрогом режиме или undefined в строгом (привязка по умолчанию). У стрелки нет своего this, и она берёт его лексически из окружающей области видимости.
Типичные ошибки
- ✗Считать, что
thisпривязан при определении, а не определяется местом вызова - ✗Ждать, что метод, оторванный от объекта, сохранит свой исходный
this
Уточняющие вопросы
- →Почему передача
obj.methodкак колбэка часто теряет егоthis? - →Чему равен
thisпри обычном вызове в строгом и нестрогом режиме?
JuniorТеорияИногдаЧто такое IIFE и зачем его использовали?
Что такое IIFE и зачем его использовали?
IIFE (Immediately Invoked Function Expression — немедленно вызываемое функциональное выражение) — это функция, выполняющаяся в момент своего определения, записываемая как (function () { ... })(). Обёртка кода в неё создаёт приватную область видимости: объявленные внутри переменные не видны снаружи, что позволяло не засорять глобальное пространство имён до того, как блочные let/const и ES-модули сделали это почти ненужным.
Типичные ошибки
- ✗Думать, что IIFE выполняется позже или асинхронно, а не сразу при определении
- ✗Считать, что переменные внутри IIFE утекают в глобальную область, а не остаются приватными
Уточняющие вопросы
- →Почему функцию нужно оборачивать в скобки, чтобы получить IIFE?
- →Как
let/constи ES-модули заменяют изолирующую роль IIFE?
MiddleТеорияИногдаЧто возвращает bind и что будет, если вызвать связанную функцию через new?
Что возвращает bind и что будет, если вызвать связанную функцию через new?
bind возвращает совершенно новую функцию (экзотическую bound-функцию), которая при вызове запускает оригинал с this, навсегда зафиксированным на привязанном значении, плюс любые заранее заданные ведущие аргументы. Оригинал сразу не вызывается.
Типичные ошибки
- ✗Думать, что
bindвызывает функцию сразу, какcall - ✗Ожидать, что привязанный
thisпереживёт вызовnewна связанной функции - ✗Считать, что заранее привязанные аргументы отбрасываются при конструировании связанной функции
Уточняющие вопросы
- →Почему
newперекрываетthis, зафиксированныйbind? - →Как частичное применение через
bindсохраняет заранее заданные аргументы подnew?
SeniorТеорияИногдаКаковы основные применения и подводные камни замыканий?
Каковы основные применения и подводные камни замыканий?
Замыкания обеспечивают приватность данных и паттерн модуля (IIFE, возвращающий методы над приватными переменными), фабрики функций и колбэки с состоянием. Классическая ловушка — баг захвата в цикле: цикл с var делит одну привязку, поэтому все колбэки видят финальное значение, тогда как let даёт каждой итерации свою. Замыкания также удерживают захваченные переменные, рискуя утечкой памяти, если их держать живыми.
Типичные ошибки
- ✗Считать, что цикл с
varдаёт каждому колбэку свою привязку, какlet - ✗Полагать, что замыкания не удерживают память, игнорируя утечки от долгоживущих захваченных ссылок
Уточняющие вопросы
- →Как именно замена
varнаletисправляет баг захвата в цикле? - →Как паттерн модуля сочетает
IIFEс замыканием, чтобы скрыть состояние?
SeniorТеорияИногдаКак this разрешается во всех разных типах вызова?
Как this разрешается во всех разных типах вызова?
Есть приоритет: new делает this свежим экземпляром; явные call/apply/bind (жёсткая привязка) задают его указанному объекту и побеждают неявную; obj.method() делает this получателем; обычный вызов по умолчанию даёт глобальный объект или undefined в строгом режиме. Стрелка игнорирует всё это — у неё нет своего this, и она берёт его лексически оттуда, где была определена.
Типичные ошибки
- ✗Думать, что неявная привязка переопределяет явный
bind, а не наоборот - ✗Ждать, что
thisстрелочной функции меняется с местом вызова, как у обычной
Уточняющие вопросы
- →Почему
bindназывают жёсткой привязкой, и может ли позднийcallеё переопределить? - →Какой
thisзахватывает стрелка, определённая внутри конструктора?