Единственная статья, которую вам нужно прочитать, чтобы понять ключевое слово «this» в JavaScript.

В этой статье мы рассмотрим важнейшую, но очень запутанную тему JavaScript - ключевое слово «this».

TL;DR

Если «это» пугает вас, не волнуйтесь! Мы узнаем, как определить значение ключевого слова «this», используя пять простых правил.

Вот эти пять простых правил:

  • Обычный - Привязка по умолчанию
  • Функция внутри объекта - Неявная привязка
  • Заимствование функций - Явная привязка
  • Использование функции для создания объектов - Новая привязка
  • Чем функция стрелки отличается от обычных - Лексическая привязка

Не беспокойтесь об этих страшных именах. Люди, занимающиеся компьютерными науками, любят называть термины так, чтобы они казались внеземными. Под капотом это просто общие концепции, которые может понять любой желающий человек.

Переменная «this» соответствует способу вызова функции. Эти правила помогают нам определять ценность this в различных сценариях.

Как только вы поймете эти правила, вы перестанете их бояться.

Прежде чем мы начнем, пожалуйста, прочтите эту статью, чтобы понять, как это работает.

Что вкратце «это»

В JavaScript всякий раз, когда вызывается функция, механизм JavaScript создает новый контекст выполнения. Этот контекст выполнения существует до тех пор, пока функция не завершит выполнение. Каждый контекст выполнения содержит переменную с именем «this».

# Правило 1. Привязка по умолчанию

При вызове функции стандартным способом, показанным выше, «this» на самом деле будет ссылаться на глобальный объект!

В браузере глобальный объект означает объект Window.

Следует помнить одно исключение - это когда включен строгий режим. Написав «use-strict», вы можете предотвратить объявление чего-либо в глобальном объекте.

# Правило 2. Неявная привязка

Если функция содержится в объекте, то на этот объект будет ссылаться «this».

Для приведенного выше ключевого слова this будет указывать на personObj

# Правило 3. Явная привязка

Мы видели, как this указывает на глобальный объект, а в другом случае - на объект, который его содержит. Разве не было бы неплохо иметь возможность контролировать, чем в конечном итоге будет эта переменная при вызове функции?

Такие слова, как call, apply и bind, обычно вызывают ужас у начинающих разработчиков. На самом деле все они являются функциями, которые можно использовать для явного задания значения «this».

Давайте разберемся с этим на примере.

Предположим, у нас есть два объекта, скажем personObj и readerObj

Оба объекта имеют свойство name. personObj имеет функцию, которая может печатать значение внутри name, но readerObj не имеет такой функции!

Здесь мы можем использовать один из трех методов - call, apply или bind.

Этот процесс называется заимствованием функции.

Мы позаимствовали метод sayName для readerObj.

Теперь мы можем распечатать свойство name, которое находится в readerObj

Мы вызываем метод sayName из personObj, но в то же время инструктируем движок JavaScript, что переменная this в методе sayName должна указывать на readerObj.

Поэтому, когда механизм JavaScript выполняет код, переменная this в функции sayName указывает не на personObj, а на readerObj.

Имеет ли это смысл?

Не только это - мы также можем передавать некоторые аргументы, когда используем функцию call.

Мы можем использовать аргумент в методе sayName.

Когда мы выполним код, мы получим вывод вместе с переданным аргументом.

Метод apply работает так же, но вместо обычных аргументов он принимает в качестве аргумента массив.

Метод bind также работает таким же образом - он может принимать обычный аргумент.

Но в отличие от call и apply - bind возвращает функцию - эту функцию можно сохранить в переменной и выполнено в будущем.

Можно увидеть использование связывания в каррировании функций - тема, которую мы рассмотрим в будущем.

# Правило 4. Новая привязка

Мы используем ключевое слово new для создания экземпляра или копии объекта. Что делает новое ключевое слово:

  • Он создает пустой объект, а затем дает указание ключевому слову this указывать на этот пустой объект.
  • Затем он добавляет оператор return this в конец этой функции.

Помните, что когда экземпляр объекта создается с использованием ключевого слова new, «this» всегда указывает на этот вновь созданный экземпляр.

Давайте разберемся в этом на примере.

Когда мы запустим этот код, что мы должны получить?

Как мы уже сказали - пустой объект!

То, что происходит под капотом,

Какие? Мы вызываем функцию?

Да!

Давайте посмотрим на все это.

Если мы поместим какое-то значение в функцию, она поместит это значение во вновь созданный объект, а затем вернет его!

Когда мы console.log(newPersonObj)

Завершим эту концепцию анимацией.

В приведенном выше примере мы используем функцию для создания объекта.

Этот тип функции известен как конструктор функции.

Помните, что в newPersonObj, в котором хранится копия personObj, переменная this указывает на пустой personObj

Теперь это имеет смысл?

Хороший! Давайте теперь разберемся с последним правилом.

# Правило 5. Лексическая привязка

С появлением ES6 у нас появились стрелочные функции. Стрелочные функции с их сверхлегким синтаксисом являются естественной заменой своим традиционным анонимным аналогам.

Чтобы явно вызвать стрелочную функцию, как и в случае с обычной анонимной функцией, вы должны сначала присвоить ее переменной:

Стрелочные функции похожи на обычные анонимные функции, за одним важным исключением - поведение этого объекта внутри функции.

В обычной функции значение «this» зависит от контекста - вызовите функцию внутри ссылки, а «this» указывает на объект ссылки; вызовите его внутри еще одной функции, например setInterval(), тогда 'this' указывает на глобальный объект окна.

Например, в следующем примере предпринимается попытка вызвать метод start() настраиваемого объекта для увеличения его свойства counter на 1 каждую секунду, хотя это не удается из-за неправильного предположения о счетчике ссылок на объект «this».

В приведенном выше примере this.counter не удается правильно сослаться на свойство счетчика объекта countup, хотя ошибка может быть не так очевидна для обнаружения. Можно ошибочно или по неосторожности предположить, что 'this' указывает на объект countup, тогда как на самом деле он указывает на глобальный объект window из-за того, что контекст 'this' вызывается внутри глобального оконного метода setInterval().

Результатом является ссылка на несуществующее свойство window.counter, которое будет постоянно возвращать NaN, когда мы пытаемся увеличить его. Чтобы правильно ссылаться на объект countup внутри анонимной функции, мы должны кэшировать ссылку на правильный объект 'this' до того, как контекст изменится на другой:

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

Сравните это с обычными функциями, где «this» является динамическим и основывается на контексте, который он вызывает, независимо от области видимости во время определения «this».

Давайте возьмем предыдущий пример, который изначально доставил нам проблемы, и посмотрим, как переход на использование стрелочной функции интуитивно решает проблему:

Мы решили проблему, просто используя стрелочную функцию.

Заключение

Если вы поняли все правила, то похлопайте себя по плечу - вы этого заслужили! Теперь вы больше не тот, кто боится самой запутанной концепции JavaScript - ключевого слова this.

В этой статье мы узнали:

  • При вызове функции стандартным способом, показанным выше, «this» фактически будет ссылаться на глобальный объект!
  • Если функция содержится в объекте, тогда «this» будет указывать на этот объект.
  • call, apply и bind - это функции, доступны нам с помощью JavaScript, чтобы изменить поведение «this» в нашей программе.
  • new ключевое слово или оператор при использовании создает пустой объект, а затем инструктирует «this» указать на этот вновь созданный объект
  • Стрелочная функция позволяет нам лексически привязать ключевое слово «this» в программе, это означает, что его значение является статическим и определяется местом, где находится ключевое слово «this». определенный.

Записка благодарности

Я хотел воспользоваться этой последней возможностью, чтобы поблагодарить вас.

Спасибо, что были здесь! Я не смог бы делать то, что делаю, без таких людей, как вы , которые последуют за мной и совершат этот прыжок веры, чтобы прочитать мой пост.

Я надеюсь, что вы присоединитесь ко мне в моем будущем сообщении в блоге и останетесь здесь, потому что я думаю, что у нас здесь есть что-то замечательное. И я надеюсь, что смогу помочь вам в вашей карьере еще много лет!

Увидимся в следующий раз. До свидания!

Больше контента на plainenglish.io