Пример замыкания с внутренней функцией и предмет замыкания в JavaScript
Что проверяют
Просят не определение, а пример и его разбор: какая именно переменная захвачена и кем. Ответ показывает, понимаете ли вы, что замыкается переменная, а не её значение, и что окружение своё у каждого вызова внешней функции.
Как отвечать
Начните с примера, где видно и общее состояние, и независимость экземпляров:
function createCounter(start) {
let count = start;
return {
inc: () => ++count,
read: () => count,
};
}
const a = createCounter(0);
const b = createCounter(10);
a.inc();
a.read(); // 1
b.read(); // 10Теперь то, ради чего вопрос задан. Замыкается не значение count, а сама переменная: inc и read ссылаются на одно связывание, поэтому вторая функция видит работу первой. При этом a и b друг другу не мешают, ведь каждый вызов createCounter создаёт новое лексическое окружение. Снаружи count недостижима, единственный вход через возвращённые функции, отсюда и приватное состояние.
Предмет замыкания это переменные внешних областей, на которые функция ссылается, а не вся внешняя функция целиком. Практическая польза та же: приватность, мемоизация, дебаунс и троттлинг с таймером внутри, фабрики обработчиков с предзаданными параметрами.
Где спотыкаются
Говорят, что замыкание запоминает значение. Классический разоблачитель это цикл с var: все колбэки видят одну переменную и её последнее значение, а let создаёт своё связывание на каждой итерации.
Ошибаются в том, где состояние общее. Два метода одного объекта делят переменную, два вызова фабрики нет. В жизни это выглядит как «счётчик почему-то сбрасывается» или «два виджета мешают друг другу».
Забывают про удержание памяти. Замкнутая ссылка на узел DOM или крупный объект живёт, пока жива функция, а не снятый обработчик и не очищенный таймер не дают сборщику мусора её отпустить.