Если когда-либо существовала более сложная тема в Javascript, то «это» было бы ею (посмотрите, что я там сделал 😏). Я не могу сосчитать, сколько раз мне приходилось угадывать привязку «this» для конкретной функции, чтобы понять смысл задачи кодирования, и все безрезультатно. Каким бы неуловимым оно ни было, его понимание обязательно принесет больше ясности. Вот простой обзор;

Ссылка THIS в javascript является привязкой среды выполнения и основана на условиях вызова или вызова объемлющей функции.

Смущенный? Давайте углубимся.

При вызове функции создается запись активации, также известная как контекст выполнения. Эта запись содержит информацию о;

  • Откуда была вызвана функция (Call-stack)
  • Как была вызвана функция
  • И какие параметры были переданы. и т. д.

Одним из свойств записи является ссылка «This». Сайт вызова функции foo находится в глобальном объекте и, следовательно, привязывается к нему, когда в foo есть ссылка на this. >. Поскольку переменная a определена в глобальном объекте как 2, вызов foo проверит глобальный объект на наличие a и выведет 2 на консоль. Этот метод разрешения ссылки «это» называется привязкой по умолчанию и является наиболее распространенным случаем вызовов функций.

Разрешение «THIS» в исполняемой функции

Теперь к яблоку раздора. Привязка по умолчанию — это наиболее распространенный (самый слабый) из четырех способов определения привязки «этого» для конкретной функции. Ниже приведены другие способы сделать это.

  1. Неявное связывание

Здесь call-site использует контекст obj для ссылки на функцию. Объекту obj принадлежит ссылка на функцию во время вызова функции. Вызов foo выдает 2 путем поиска значения a в его привязке this, которая в настоящее время является obj.

Одна из распространенных проблем с этим типом привязки заключается в том, что ссылка this может быть неявно потеряна из-за обратных вызовов функций. В случае событий в javascript этот контекст напрямую переопределяется, чтобы указать на экземпляр DOM, для которого было вызвано событие.

2. Явная привязка

Вызов foo с явной привязкой с помощью foo.call(..) позволяет нам заставить его «this» быть obj. Недостатком этого метода является то, что его можно применять только на месте вызова, что иногда не находится под нашим контролем, например, в случае обратных вызовов, когда «этот» контекст может быть потерян или заменен. Чтобы обойти это препятствие, мы применяем более строгий вариант явного связывания, который называется жесткое связывание.

В жесткой привязке мы создаем функцию bar(), которая внутри вручную вызывает foo.call(obj), тем самым принудительно вызывая для этого foo с привязкой obj. Независимо от того, как вы позже вызовете функциональную панель, она всегда будет вручную вызывать foo с помощью obj. Эта привязка явная и сильная.

Поскольку жесткая привязка является таким распространенным шаблоном, она снабжена встроенной утилитой начиная с ES5 — Function.prototype.bind. И используется так: foo.bind(obj)

3.Новый оператор

Когда функция вызывается с new перед ней, иначе называемой вызовом конструктора, автоматически выполняются следующие действия:

  • Совершенно новый объект создается (иначе конструируется) из воздуха.
  • Вновь созданный объект является [[Prototype]]-связанным.
  • Вновь созданный объект устанавливается как привязка «this» для этого вызова функции.

Если функция не возвращает свой собственный альтернативный объект, новый вызов функции автоматически вернет вновь созданный объект, который служит привязкой «this» для функции.

Лексический Это

В ситуациях, когда идентификация «этой» ссылки может оказаться проблематичной, ES6 дает нам способ полностью избежать игры в угадайку. Вместо четырех стандартных правил привязки стрелочные функции ES6 используют лексическую область видимости для привязки «this», что означает, что они наследуют привязку «this» (какой бы она ни была) из вызова включающей ее функции.

Важно отметить, что стрелочные функции по существу отключают традиционный этот механизм в пользу более широко понимаемой лексической области видимости, предоставляя альтернативу использованию bind(..) на функция.

Заключение

Это было поучительно, верно? Мы не только поняли «ЭТО», мы также научились использовать стрелочные функции, чтобы использовать «это» объемлющей области видимости через лексическую область видимости. Надеюсь, вы больше никогда не поймете, что такое «это». Чао 👋

Следующая остановка — Прототипы

Рекомендации

Вы не знаете JS: это и прототипы объектов https://www.amazon.com/You-Dont-Know-JS-Prototypes/dp/1491904151