Какие знаешь проблемы у this в JavaScript

Ответ

В JavaScript this может вызывать проблемы из-за динамического контекста:

  1. Потеря контекста в колбэках:
const obj = {
  name: 'Test',
  logName() {
    console.log(this.name);
  }
};

setTimeout(obj.logName, 100); // undefined
  1. Разный контекст в строгом ('use strict') и нестрогом режиме:
  • В нестрогом режиме this в функции без контекста = window
  • В строгом режиме = undefined
  1. Методы как пропсы в React могут терять контекст:
<button onClick={this.handleClick}>Click</button> // без bind потеряет this
  1. Стрелочные функции не имеют своего this, берут из внешнего контекста, что может быть неожиданным.

Решения:

  • Использовать bind()
  • Стрелочные функции
  • Сохранение контекста в переменную (const self = this)

Ответ 18+ 🔞

Да ты посмотри на эту хуйню, этот this в JavaScript! Ну реально, маньяк какой-то, контекст меняет как перчатки, сука. Один раз смотришь — он один, моргнул — уже другой. Пиздец просто.

Вот, например, классика жанра, потеря контекста. Делаешь ты объект, красивый такой, с методом.

const obj = {
  name: 'Test',
  logName() {
    console.log(this.name);
  }
};

Всё вроде ок, вызываешь obj.logName() — «Test» в консоли, красота. А потом, блядь, передаёшь этот метод куда-нибудь, в setTimeout например, и начинается пиздец.

setTimeout(obj.logName, 100); // undefined

И что выводит? undefined! А где имя? А его нет! Потому что этот ебучий this теперь ссылается не на наш obj, а на какой-то другой контекст, на глобальный window скорее всего. Собака сука, обманщик.

А ещё есть разница между строгим режимом и нестрогим, ёпта! В нестрогом, если функция без контекста, this будет равен window. А в строгом ('use strict') — undefined! Ну ты представляешь? Один и тот же код в зависимости от режима ведёт себя по-разному! Это ж какой надо быть извращенцем, чтобы такую хуйню придумать!

В React, о, это отдельная песня. Передаёшь метод как пропс в обработчик:

<button onClick={this.handleClick}>Click</button>

А он, блядь, теряет контекст! Кликаешь — и получаешь ошибку, потому что this внутри handleClick — уже не твой компонент, а какая-то хуйня. Волнение ебать, терпения ноль!

И стрелочные функции, эти хитрожопые ублюдки! Они своего this не имеют, берут его у родителя. Иногда это спасает, а иногда так неожиданно выстреливает, что сам от себя охуеешь. Думаешь, что всё под контролем, а они тебе — раз, и контекст от бабушки какой-нибудь утащили.

Что делать-то с этим бардаком? Варианты есть, слава богу.

  • bind() — старый добрый привязыватель контекста. Жёстко прибивает this к определённому значению. Как смирительная рубашка для контекста.
  • Стрелочные функции — если нужно, чтобы this был таким же, как снаружи. Но осторожно, они не для всего.
  • Старый дедовский способconst self = this. Сохраняешь контекст в переменную и потом внутри любой вложенной функции используешь self. Просто, как три копейки, но работает.

В общем, this — это такой пидарас шерстяной в мире JavaScript. С ним надо постоянно быть начеку, а то наебёт так, что мало не покажется. Чих-пых его в сраку!