Простые правила того, что такое «это» в функциях Javascript

this сложно. this относится к контексту внутри функции, но контекст отличается в зависимости от того, как объявлена ​​функция.

Мы рассмотрим бесчисленное множество способов написания функции Javascript и узнаем, какое значение имеет this. Обратите внимание: вы можете найти суть Github с примерами, которые я сделал в статье, если вам нужен быстрый способ скопировать/вставить код и попробовать его самостоятельно!

Анонимные функции

Анонимная функция — это функция без имени. Например:

function() {
   console.log(this.constructor.name);
}

this внутри анонимной функции является глобальным объектом (например, окно в браузере).

Вот пример объекта Javascript с анонимными функциями внутри него.

Когда вы запускаете код слева, вы ожидаете, что this будет глобальным объектом Window, как показано справа.

Анонимные функции часто используются для IIFE или в качестве обратных вызовов.

Стрелочные функции

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

В приведенном ниже примере объемлющей областью во время создания является объект дракона.

Вышеприведенный код такой же, как в примере для анонимных функций, но sayHello — это функция со стрелкой, а обратный вызов внутри forEach также является функцией со стрелкой. В данном случае this — это объект дракона.

Функции со стрелками предотвращают управление контекстом с помощью .call и .apply .

Это означает, что даже если вы попытаетесь привязать контекст к функции, это не сработает, если эта функция является стрелочной. Я вернусь к этому позже в статье.

Функции, называемые методами

Если функция вызывается как метод (например, myObj.myMethod()), даже если это анонимная функция, this по-прежнему является объектом, для которого функция является свойством. В приведенном ниже примере, если мы назначим sayHello как свойство Dragon, this будет объектом Dragon.

this внутри анонимной функции является экземпляром Dragon, если анонимная функция является свойством объекта Dragon.

Javascript-объекты

Однако внутри объекта Javascript this отличается для функции стрелки от анонимной функции.

Как видите, this внутри функции стрелки равно Window, в то время как this внутри нашей анонимной функции по-прежнему является нашим объектом-драконом, Изерой.

Причина здесь в том, что объемлющая лексическая область для функции стрелки внутри объекта Javascript, объявленного на глобальном уровне, по-прежнему является глобальным объектом Window.

Подать заявку, позвонить и это

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

Например, для класса DragonBound вместо вызова анонимной функции sayHello() как есть мы используем .callsayHello.call(this). Это передало объект дракона в функцию sayHello в качестве контекста для this.

Мы ожидаем, что консоль покажет

“‘this’ is Window. My name is result”
“‘this’ is DragonBound. My name is Alexstraza”

Собственно, вот что у нас получилось:

.apply() работает аналогично. Они отличаются тем, как аргументы передаются в функцию.

Опять же, .call и .apply НЕ будут работать со стрелочными функциями, как показано ниже:

Привязка alexstraza к методу ysera не будет работать, если метод объявлен со стрелочной функцией.

Я планирую более подробно рассказать о том, как реализованы .call, .apply и .bind, в следующей статье. Следите за обновлениями!

Вот он, суть Github с примерами из этой статьи:

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