JavaScript: ключевое слово this для начинающих

JavaScript: ключевое слово this для начинающих

От автора: иногда бывает сложно объяснить понятие ключевого слова JavaScript this, а также для чего оно нужно. Но существует пять общих правил, с помощью которых можно определить рамки this. Есть случаи, которые не подходят под эти правила, но они покрывают большую часть… приступим!

Значение this обычно определяется контекстом выполнения функций. Контекст выполнения – это то, как функция вызывается.

Важно знать, что this может быть разным (отсылать на что-то другое) для каждого вызова функции.

Ничего страшного, если №1 и №2 пока что вам непонятны. Они станут понятны к концу статьи.

№1 Глобальный объект

Так, определение мы теперь знаем. Давайте вернемся на минуточку. Откройте Chrome Developer Console (Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J) и введите следующее:

Что получится?

Объект window! Потому что в глобальной области видимости this отсылает к глобальному объекту. В браузере глобальный объект это window.

Чтобы вы лучше поняли, почему this отсылает к объекту window, давайте разберем его подробнее. Создайте в консоли новую переменную и присвойте ей имя:

Теперь к этой переменной можно обращаться через:

Но знали ли вы, что все переменные, объявленные в глобальной области видимости, привязаны к объекту window? Проверим это:

Круто. То есть раньше когда мы запустили console.log(this) в глобальном контексте, вы знали, что this вызывается на глобальном объекте. А так как в браузере глобальный объект это this, то теперь понятно, почему:

Теперь поместим this внутрь функции. Вспомните определение: значение this обычно определяется тем, как вызывается функция. Как думаете, что возвращает функция? Скопируйте код ниже в консоль браузера и выполните его.

И опять ключевое слово this возвращает глобальный объект (window). Все потому что this не внутри объявленного объекта, поэтому берется объект по умолчанию (window). Пока что концепция может показаться сложно, но по мере прочтения статьи все станет понятнее. Замечание – если вы не используете строгий режим, то this в примере выше будет undefined.

№2 Объявленный объект

Когда ключевое слово this используется внутри объявленного объекта, значение this устанавливается к ближайшему родительскому объекту, на котором вызван метод. Посмотрите код ниже, где я определил объект person и использовал this внутри метода full

Чтобы лучше проиллюстрировать связь this с объектом person, скопируйте код ниже в консоль браузера. Код почти как сверху, мы просто выводим console.log(this), чтобы посмотреть что вернется.

Как видите, консоль возвращает объект person, что подтверждает, что this приняло значение person.

И еще одно, прежде чем мы продолжим. Помните, что мы сказали, что значение this устанавливается в ближайший родительский объект вызываемого метода? А что будет, если объекты вложены? Посмотрите код ниже. Там у нас объект person с такими же ключами first, last и full. Однако в этот раз мы вложили объект personTwo. У personTwo те же три ключа.

Что будет, если вызвать два метода full? Узнаем.

Значение this устанавливается в ближайший родительский объект вызываемого метода. При выполнении person.full() внутри функции this ограничен объектом person. Однако при вызове person.personTwo.full() внутри функции this ограничен уже объектом personTwo!

№3 Ключевое слово new

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

Разберем пример:

Вы можете подумать, что this ограничен глобальным объектом – и вы будете правы… пока мы не добавим ключевое слово new. Если использовать new, то значение this устанавливается в пустой объект. В нашем случае myCar.

Нужно понять, что делает слово new. Это совершенно новая тема. Пока что просто если видите new, знайте, что this отсылает к новому пустому объекту.

№4 Call, Bind, Apply

Последнее, но не менее важное, мы можем явно задавать значение this через call(), bind() и apply(). Три метода очень похожи, но важно понять их различия.

Call и Apply выполняются сразу же. Call принимает любое количество параметров: this, после которого следуют дополнительные аргументы. Apply принимает только два параметра: this, после которого идет массив дополнительных аргументов.

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

Функция add логирует NaN (не число). Потому что this.a и this.b не определены. Они не существуют. Вы не можете сложить число с чем-то неопределенным.

Введем в уравнение объект. С помощью call() и apply() мы можем вызвать функцию с нашим объектом:

Когда мы используем add.call(), this должен быть ограничен первым параметром. Остальные параметры передаются в вызываемую функцию. Поэтому внутри add() this.a отсылает к ten.a и ten.b, а нам возвращается 1+2+3+4 или 10.

Add.apply() работает так же. Первый параметр ограничивает this. Второй параметр – массив аргументов для функции.

А Bidn? Параметры в bind() идентичны call(), но bind() не выполняется незамедлительно. bind() возвращает функцию с контекстом this. Поэтому bind() полезен, когда мы не знаем все аргументы. Пример поможет прояснить:

Скопируйте код выше в консоль и выполните следующее.

Круто. Все по старому. А что если использовать значение large.a? Можно использовать call/apply:

А что если мы еще не знаем все три аргумента? Можно взять bind:

Если вывести в консоли console.log нашу переменную выше bindTest, мы увидим, с чем работаем

Помните, что с bind возвращается функция, у которой уже есть свой this! Поэтому наш this ограничен объектом large. Мы также передали наш второй аргумент 2. Как только мы узнаем остальные аргументы, мы можем их передать:

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

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

Это настолько большая тема, что я написал целую статью Arrow Functions for Beginners

Заключение

У вас получилось! Теперь в большинстве случаев вы сможете понять, к чему отсылает this! Запомните пару вещей:

Значение this обычно определяется контекстом вызова функций.

В глобальной области видимости this отсылает к глобальному объекту (window).

При использовании new (конструктор), this ограничен новым создаваемым объектом.

Значение this можно явно задать через call(), bind() и apply()

Стрелочные функции не привязывают this – this ограничивается лексически (т.е. по оригинальному контексту)

Автор: Brandon Morelli

Источник: //codeburst.io/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: