Как обращаться к объекту массива через this в JavaScript
Что проверяют
Понимаете ли вы, что this определяется способом вызова, а не местом объявления функции. Вопрос обычно крутится вокруг колбэков методов массива, где контекст теряется. Следом спрашивают про стрелочные функции, bind и второй аргумент forEach.
Как отвечать
Разберите типовые ситуации:
- метод объекта: в вызове
obj.getItem(i)у обычной функцииthisравенobj, поэтомуthis.items[i]работает. Ноconst f = obj.getItem; f(1)уже теряет контекст: в строгом режиме и в ES-модуляхthisбудетundefined; - колбэк метода массива: в
this.items.forEach(function (x) { this.total += x })обычная функция получает свойthis, и это не ваш объект. Решения: стрелочная функция, которая берётthisснаружи, второй аргументthisArgуforEach,map,filter,some,every, илиbind(this); - функция как элемент массива: вызов
arr[0]()это вызов через доступ к свойству, поэтомуthisвнутри равен самомуarr. Классическая задачка на собеседованиях; - массив как
this: в методахArray.prototypeи в классеclass Stack extends Arraythisуказывает на сам массив, работаютthis.lengthиthis.at(-1); callиapply:Array.prototype.map.call(arguments, fn)запускает метод массива на массивоподобном объекте, хотя сегодня прощеArray.from.
В классах та же история: метод, переданный как обработчик события, теряет this, поэтому используют стрелочные поля класса или bind в конструкторе.
Где спотыкаются
Пишут стрелочную функцию как метод объекта: getItem: (i) => this.items[i]. У стрелки нет своего this, она возьмёт внешний, и items там не окажется.
Передают thisArg вместе со стрелочным колбэком и ждут, что он сработает. Стрелке второй аргумент безразличен.
Говорят, что в глобальном контексте this всегда window. В ES-модулях на верхнем уровне это undefined, у обычной функции в строгом режиме тоже, а переносимый способ получить глобальный объект это globalThis.