Как задать this явно для функции в JavaScript
Что проверяют
Понимаете ли вы, что this определяется способом вызова, а не местом объявления функции, и знаете ли правила приоритета. Следом обычно спрашивают, что будет с bind у стрелочной функции и почему в React-компоненте на классах теряется контекст.
Как отвечать
Три метода задают this явно:
call(thisArg, a, b): вызывает функцию сразу, аргументы перечисляются через запятую;apply(thisArg, [a, b]): то же, но аргументы массивом. Со spread-синтаксисом нужен реже:Math.max(...arr)вместоMath.max.apply(null, arr);bind(thisArg, ...args): не вызывает, а возвращает новую функцию с навсегда привязаннымthisи, при желании, частью аргументов.
Ещё варианты: второй аргумент thisArg у forEach, map, filter и Reflect.apply(fn, thisArg, args).
Покажите порядок приоритета: вызов через new сильнее всего, затем явная привязка, затем неявная (obj.method()), затем вызов по умолчанию. В строгом режиме по умолчанию this равен undefined, в нестрогом это globalThis, туда же в нестрогом режиме уходят переданные null и undefined. Модули и тела классов всегда строгие.
У стрелочных функций нет своего this: они берут его из окружающей области при создании, и call, apply, bind его не меняют. Поэтому их удобно отдавать колбэками, но не стоит делать методами объекта-литерала.
Практический случай: метод, переданный как setTimeout(obj.method, 100) или обработчиком события, теряет контекст. Решение: obj.method.bind(obj), стрелочная обёртка или поле класса со стрелочной функцией.
Где спотыкаются
Пытаются перепривязать уже привязанную функцию: fn.bind(a).bind(b) сохранит a, повторный bind добавляет только аргументы.
Ожидают, что call поменяет this у стрелочной функции. Вызов пройдёт без ошибки, но this останется внешним.
Пишут onClick={this.handle.bind(this)} прямо в рендере. На каждый рендер создаётся новая функция, и мемоизированные дочерние компоненты перерисовываются зря; привязывайте один раз в конструкторе или через поле класса.