Приведите пример разницы this и замыкания в JavaScript
Что проверяют
Различаете ли вы две независимые вещи: переменные функция берёт оттуда, где объявлена, а this получает в момент вызова. Смешение этих правил даёт самые частые баги в обработчиках и коллбэках, поэтому вопрос и любят.
Как отвечать
Покажите на одном объекте, что теряется, а что нет:
const counter = {
count: 0,
start() {
const self = this;
setTimeout(function () {
console.log(this.count); // undefined, this уже не counter
console.log(self.count); // 0, переменная захвачена замыканием
}, 0);
},
};
counter.start();Вывод из примера простой. self доступен, потому что вложенная функция помнит окружение, в котором создана. А this внутри обычной функции определяется тем, как её позвали, и setTimeout зовёт коллбэк сам, без объекта слева от точки.
Второй показательный случай: const { start } = counter; start(). Метод, оторванный от объекта, теряет this, а замкнутые переменные не теряются никогда. Отсюда и лечение: для this это стрелочная функция или bind, для переменных лечить нечего.
Где спотыкаются
Говорят, что стрелочная функция «привязывает this к родителю». Своего this у неё просто нет, она ищет его во внешней области как обычную переменную, и поэтому call с bind на неё не действуют.
Считают приём const self = this отдельной сущностью. Это и есть перенос значения this в замыкание, ровно то, что позже стали делать стрелкой.
Путают правила для верхнего уровня. В обычной функции без строгого режима this равен глобальному объекту, а в модуле и в строгом режиме там undefined, поэтому ответ «всегда window» неверен для любой современной сборки.