На картинке — код на JavaScript с ошибкой, который написал специально для Хабра руководитель группы разработки интерфейсов компании «Криптонит» Василий Беляев.
Кто увидел, где ошибка и как её можно решить — пишите в комментариях! А решение этой ошибки оставили под картинкой.

Если запустим этот код, то получим ошибку
Uncaught TypeError: this.clearHistory is not a function
Проблема находится на строчках 11-13 (на картинке)
this.timeout = setTimeout (function () {
this.clearHistory();
}, 0);
Когда мы вызываем setTimeout, то вызываем метод объекта window, и меняем область видимости с нашего конструктора на window ( window.setTimeout() ).
Именно по этой причине у нас метод clearHistory пытается вызываться у объекта window ( window.clearHistory() )
Как можно решить эту проблему?
Вариант 1
const MyItem = function () {
this.clearStorage = function () {
console.log ('Очищаем хранилища...');
};
this.clearHistory = function () {
console.log ('Очищаем историю...');
};
};
MyItem.prototype.refresh = function () {
this.clearStorage();
this.timeout = setTimeout (() => {
this.clearHistory();
}, 0);
};
const mуItem = new MyItem();
mуItem.refresh();
Заменить анонимную функцию на стрелочную функцию. У них отсутствует свой контекст, и они работают в контексте области видимости, включающий их самих.
Вариант 2
const MyItem = function () {
this.clearStorage = function () {
console.log ('Очищаем хранилища...');
};
this.clearHistory = function () {
console.log ('Очищаем историю...');
};
};
MyItem.prototype.refresh = function () {
this.clearStorage();
this.timeout = setTimeout (
this.clearHistory.bind(this), 0
);
};
const mуItem = new MyItem();
mуItem.refresh();
Явно передать контекст через метод .bind()
Вариант 3
const MyItem = function () {
this.clearStorage = function () {
console.log ('Очищаем хранилища...');
};
this.clearHistory = function () {
console.log ('Очищаем историю...');
};
};
MyItem.prototype.refresh = function () {
this.clearStorage();
const self = this;
this.timeout = setTimeout (() => {
self.clearHistory();
}, 0);
};
const mуItem = new MyItem();
mуItem.refresh();
Выносим контекст в отдельную переменную и работаем с ней. Этот вариант подойдет для поддержки старых браузеров.
А как бы вы решили эту ошибку?